首页 > 技术文章 > 使用Prerender.io为angular项目做SEO

suiblog 2016-02-03 18:56 原文

现在的项目的为了更好的分工明确,降低耦合都开始采用前后端分离的形式进式开发,我们也采用这种开发形式,前端用angular开发。虽说刚开始也遇各种坑,但是后期熟悉了之后简直爽呆。一个比较大的坑就是SEO问题,前后端分离页面的路由一般都是放在前端的,用hashBang的方式控制路由。但是这会出现一种情况页面无法被搜索引擎抓取,这对于SEO简直就是灾难。
有问题就有解决办法,一般的做法就是在服务器加一个可以渲染出静态页面的中间件,类似于phantomjs,zimbile.js,只要发现是搜索引擎的蜘蛛来爬的话就返回静态页面。而Prerender.io就一个现成的工具。
 
Prerender.io 是一个兼容多种不同平台(包括Node,PHP和Ruby)的一个服务。该服务是完全开源的,但是如果你不想搭建一个你自己的SEO服务器的话,你可以使用他们提供的解决方案。Prerender的人们认为,SEO是一件正确的事,并不是一个特权,他们已经做了一些了不起的工作来扩展他们的解决方案,添加了很多自定义的功能和插件。
 
下面我们就来看看如何使用:
 
前端(客户端)配置

url中#的形式

在定义了AngularJS代码的app.js中,我们需要这句代码添加到我们的路由配置中:$locationProvider.hashPrefix('!'); 这个方法会重写你的URL。相对于标准的地址http://localhost:3000/#/home你的url地址看起来将会是类似http://localhost:3000/#!/home 的形式

如果你使用的是html5模式(html5Mode),你不会看到任何区别。

URL里面的#!非常重要,因为它会告诉爬虫你的程序有AJAX内容,需要它做一下AJAX抓取转换。

angular.module('myApp').config([  
    '$locationProvider',
    function($locationProvider) {
        $locationProvider.hashPrefix('!');
    }
]);

google等搜索引擎会识别带‘#!'的地址把它转变为‘?_escaped_fragment_=’。

比如,谷歌发现的地址 

http://www.example.com/#!/user/123

它会向服务器发送这种请求

http://www.example.com/?_escaped_fragment_=/user/123

 

url中没有#的形式(采用html5 push state )
 
1.配置index.html
 
要在主页的<head>中<meta name="fragment" content="!">。这个meta标签将告诉搜索引擎的爬虫,这个网站有动态的JavaScript内容需要爬取。
<base href="/">
 
2.配置app.js
 
相比上边的配置会多一行代码。
angular.module('myApp').config([  
    '$locationProvider',
    function($locationProvider) {
        $locationProvider.hashPrefix('!');
        $locationProvider.html5Mode(true);
    }
]);    
如果采用html5mode的形式,谷歌发现url后会在后边加上?_escaped_fragment_=
 
比如,谷歌发现的地址
http://www.example.com/user/123
会发送这样的请求
 
http://www.example.com/user/123?_escaped_fragment_= 

服务器端配置
 
首先在https://prerender.io 注册一个账号并获取token。
它的官网上有多种环境的配置,比如node.js、ruby、nginx、apache等等,这里就只说apahce的配置。
它提供的是.htaccess的配置文件,所以先确认是否已经启用.htaccess文件。然后在.htaccess文件中加入以下配置
<IfModule mod_headers.c>
    RequestHeader set X-Prerender-Token "your token"
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]

    <IfModule mod_proxy_http.c>
        
        RewriteCond %{HTTP_USER_AGENT} baiduspider|facebookexternalhit|twitterbot|rogerbot|linkedinbot|embedly|quora\ link\ preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator [NC,OR]
        RewriteCond %{QUERY_STRING} _escaped_fragment_
        
        # Only proxy the request to Prerender if it's a request for HTML
        RewriteRule ^(?!.*?(\.js|\.css|\.xml|\.less|\.png|\.jpg|\.jpeg|\.gif|\.pdf|\.doc|\.txt|\.ico|\.rss|\.zip|\.mp3|\.rar|\.exe|\.wmv|\.doc|\.avi|\.ppt|\.mpg|\.mpeg|\.tif|\.wav|\.mov|\.psd|\.ai|\.xls|\.mp4|\.m4a|\.swf|\.dat|\.dmg|\.iso|\.flv|\.m4v|\.torrent|\.ttf|\.woff))(.*) http://service.prerender.io/http://example.com/$2 [P,L]
    </IfModule>

    # Rewrite everything else to index.html to allow html5 state links
    RewriteRule ^ index.html [L]
</IfModule>

要确保mod_headers、 mod_rewrite、mod_proxy_http三个模块都已经启用。

 

配置成功后在prerender.io的cached pages会有它缓存页面,这里也可以自己手动添加。
 
 
 
搜索引擎的抓取情况会这Crawl stats中反应出来。
 
接下来就看看网站的在各个搜索引擎的收录情况吧,google还是收录比较快的,百度都无力吐槽了实在太慢了,反正我配置好一个星期之内百度是一点反应都没有,不知道时间长了怎么样。
暂时先这样。
 
参考
https://prerender.io/js-seo/angularjs-seo-get-your-site-indexed-and-to-the-top-of-the-search-results/
https://scotch.io/tutorials/angularjs-seo-with-prerender-io
http://www.oschina.net/translate/angularjs-seo-with-prerender-io

推荐阅读