AngularJS 化解 SEO 难点

是因为 AngularJS
再次回到的是HTML模板,实际的内容供给履行JS以往才会填充进去,导致百度抓取蜘蛛抓不到,因而产生了
AngularJS 的 SEO
难点。经过几天的钻探试验,大家的消除方案是那样的:在后台弄叁个 PhantomJS
服务,判断是百度蜘蛛的央求后,就把请求转载给
PhantomJS,由它来表达施行JS,并赶回输出给百度蜘蛛。
下边详细说一下切实可行完成:
后端的类型选拔PHP的Zend一框架写的,只用于提供数据接口,前端选择AngularJS一。项目安插在Ubuntu上的Apache上边的。

搭建后端js环境

率先,angular项目中.htaccess须要加上几行,变成那样:

RewriteEngine On

 RewriteCond %{REQUEST_FILENAME} -s [OR]
 RewriteCond %{REQUEST_FILENAME} -l [OR]
 RewriteCond %{REQUEST_FILENAME} -d
 RewriteRule ^.*$ - [NC,L]

RewriteCond %{HTTP_USER_AGENT} baiduspider|Googlebot|facebookexternalhit|twitterbot|rogerbot|linkedinbot|embedly|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|Bingbot|360Spider|Yisouspider|Sogouspider [NC]
RewriteRule (.*) http://seo.xxx.com/url/http://www.xxx.com/$1 [P,L]

RewriteRule ^ /index.html

代表壹旦请求来自搜索引擎蜘蛛,则重定向http://seo.xxx.com。我们在这个域名上部署了一个
PhantomJS 服务。

先弄node环境:

var express = require('express')
var app = express()
app.get('/url/http://*', function (req, res) {
    var content = '';
    var ourl = req.params[0];
    if(!(ourl.indexOf('.css')>-1 || ourl.indexOf('.js')>-1 ||ourl.indexOf('.png')>-1)){
        var url = "http://"+req.params[0].replace('_','#');
        var exec = require('child_process').exec, last = exec('casperjs casperjs_process.js '+url);
        last.stdout.on('data', function (data) {
            content += data;
        });
        last.on('exit', function (code) {
            res.send(content);
        });
    }
})
app.listen('3000','127.0.0.1');

再弄 PhantomJS 服务

var casper = require('casper').create(
    {
        pageSettings: {
            loadImages: false,
            loadPlugins: true,
            userAgent: 'Mozilla/5.0.8 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36 LBBROWSER'
        },
        logLevel: "debug",//日志等级
        verbose: false, // 记录日志到控制台
        waitTimeout:5000
    }
);
var url = casper.cli.get(0);
casper.start(url, function() {});
casper.waitForSelector('.ajax-end', function() {});
casper.then(function(){
    this.echo(this.getPageContent());
});
casper.run();

那些服务会解释施行全部JS然后再次回到带有内容HTML响应数据给百度蜘蛛。

请求404的问题

取消”#”之后,能够让百度蜘蛛直接待上访问大家的各样页面了,请求来了,判定为百度蜘蛛,则转载给
PhantomJS
来处理,但问题也应运而生了,用户平时的造访却成为了40四!那是因为UBMWX3L中“#”前面包车型大巴有的是AngularJS设定的路由规则,跟小编后端未有其余关系,所以会转到40四,并回到了。
消除办法正是重写.htaccess规则,让40四指向index.html,那样就又走前端路由了。进入符合规律的前端路由,发送
ajax 请求后端数据再拓展页面渲染。
.htaccess文件如下,放/public/根目录下:

RewriteEngine On

 RewriteCond %{REQUEST_FILENAME} -s [OR]
 RewriteCond %{REQUEST_FILENAME} -l [OR]
 RewriteCond %{REQUEST_FILENAME} -d
 RewriteRule ^.*$ - [NC,L]

RewriteRule ^ /index.html

要知道原php项目布局中是指向index.php的。改成那些重写规则,就发出一个新题材,php框架的入口文件index.php也在/public/目录上面,当前端发送ajax请求时,暗中认可接收请求的是index.html,而不是index,php,那就造成ajax请求无法抵达。
在前边没有去掉“#”的时候,访问http://www.xxx.com/\#/path/sss,请求只到达http://www.xxx.com,重定向到index.html,然后AngularJS读取history对象获得URL,进行路由控制,发出ajax请求(http://www.xxx.com/path/sss),进入index.php,重临相应数额。
笔者们的消除办法正是把前端项目和后端项目分离出来,前端项目用原始的域名:http://www.xxx.com,而后端项目用:http://api.xxx.com,这样,后端php默认指向index.php,前端项目默认指向index.html。需要在apache中设置一下跨域可访问。为了方便部署,直接把前端项目命名为angular并放在public目录下面,实际上这是两个项目。
前者项目

<VirtualHost *:80>
    ServerName www.xxx.com
    DocumentRoot /path/xxx/public/angular
    DirectoryIndex index.html
    <Directory /path/xxx/public/angular>
    AllowOverride all
    require all granted
    </Directory>
</VirtualHost>

后端项目

<VirtualHost *:80>
    ServerName api.xxx.com
    DocumentRoot /path/xxx/public/
    DirectoryIndex index.php
        Header set Access-Control-Allow-Origin "http://www.xxx.com"
        Header set Access-Control-Allow-Credentials true
    <Directory /path/xxx/public/>
    AllowOverride all
    require all granted
    </Directory>
</VirtualHost>

到近日截止,“#”去掉了,用户也能健康访问了,下边正是拍卖抓取了。

去掉URL中的“#”

由于 AngularJS 的原因,生成的 URL
中带有“#”,AngularJS必要通过“#”后边的部分来拓展页面路由,但百度蜘蛛看不到USportageL中#从此现在的片段,所以首先步正是去掉
U奇骏L中的 “#”。
js/config/reoute.js 中注入 $locationProvider
对象,$locationProvider要求页面内定<base>路线,那样去掉了#现在能能科学加载js,css文件。

.config(['$stateProvider', '$urlRouterProvider','$httpProvider','$locationProvider',
    function($stateProvider,$urlRouterProvider,$httpProvider,$locationProvider){
        // ...
        $locationProvider.html5Mode(true);

下一场是index.html,那是根本的沙盘,js,css路径是对峙于<base>的。

<html>
// ...
<head>
    <script type="text/javascript" src="/dist/js/vendor.js"></script>
    <script type="text/javascript" src="/dist/js/app.js?v=1.0.3"></script>

    <base href="/">
</head>
<body>

相关文章