分享 Angular 的 SEO 问题

xieyu33333 · 2013年11月09日 · 最后由 xieyu33333 回复于 2013年11月10日 · 8470 次阅读

之前和朋友们讨论过 Angular 的 SEO 的问题,后来在测试一个叫 angular-scafford 的 gem 的时候发现他的这个机制很有趣,不知道能否解决这个问题。 后面的内容从我的 blog 直接搬运了,原地址 http://textlearn.org/blogs/96
前提之一是服务端渲染的页面 layout 和 Angular 的 index 页面通用,例如:

<html>
  <head>
    <link href="http://test.css" media="screen" rel="stylesheet">
    <script type="text/javascript"  src="angular.js"></script>
    <script type="text/javascript"  src="angular-resource.js"></script>
  <head>
  <body>
    <div ng-view>
       .................
   </div>
  <body>
</html> 
/*服务端的模板和Angular的模板都加载在省略号的地方。*/

还需要的是在 angular 的路由中添加 $locationProvider.html5Mode true,来去除#符号,让 Angular 的 route 和服务端的 route 能够对应起来。

然后我们就可以正常编写服务端和 angular 的代码,当一个客户端 http 请求发送过来时,我们会返回给他服务端渲染的代码。加载页面的同时,angular-resource 这个插件会向服务端再发送一条 content-type=json 的请求。

一旦获取了 json 数据,angular 就开始执行代码,将......处原先将要加载的服务端渲染文档替换成 angular 生成的内容 (前提是前面提到的服务端和 angular 共用同一个 layout)。此时我们查看网页源代码,会发现只有一组 json 数据。因为查看源代码显示的是最近的一次请求得到的数据。

而如果刷新查看源代码这一页,由于查看源代码页只是发送一条对 html 的请求,而并不会执行 html 中的 js,因此刷新后就可以得到服务端渲染出的页面了。

也就是说,我们看到的内容和 js 能否执行是有关系的。如果 angular.js 能够执行,我们将看到 angular 的内容,整个网站相当于单页应用,除了刷新和第一次请求外,客户端和服务端的交互都是通过 json 来实现,如果不能,则看到的是服务端渲染的内容。

这样在兼容性方面也可以做到 IE9 以下用户走服务端渲染的页面,其它用户则走 angular 的逻辑。

如果是简单的 curl 地址,或者一些无法执行 js 的网络爬虫,无疑会抓取到服务端渲染的内容。不过对于百度和 Google 的抓取机制我就不清楚了,无法确定能否收录。

最早为了解决 SPA 的 SEO 问题,google 和 twitter 共同发明了 hash ban, 只要是有 hash ban 的地方,google 都会认为此页面是一个 router 路径,会加载页面并执行完 javascript 以得到最终的页面内容。

当然,twiiter 在使用这个解决方案一段时间以后,最终还是采用了纯路径的 SPA 效果。技术细节无非就是--- 从某一功能页面进入以后,所有的链接点击全部拦截掉,使用 router 来替换以达到 SPA 的效果。 如果用户收藏了某个 link 或者直接获得某个 link 进入,则从服务器端渲染出整个页面以及相关的 javascript.

对于搜索引擎而言,只有需要的关键词在 meta 和 body 里面出现,就差不多达到了 SEO 的效果。

这样的实现方案无疑增加了代码的难度,你必须有前端代码以及后端段代码,还要保证逻辑是一致的。所以 nodejs 的解决方案能够更自然的解决这个问题。不过很多人取巧,使用的技巧是当用户直接访问某个 link 的时候,计算出该 router 需要的数据,直接赋予某个 javascript 变量,从而最大限度的复用客户端的代码。

至于百度,目前没看到是否支持 hash ban 的证据,可能只能通过 lz 说的方法来实现动态内容的 SEO.

#1 楼 @jeff_duan 不懂 nodejs,能大概介绍一下 nodejs 的解决方案的原理么?

$locationProvider.html5Mode true

貌似会破坏所有 a 链接。Angular 到现在都没有办法修复这个算是 bug 的问题。我的办法就是把 Rails 和 Angular 取长补短。需要 SEO 的页面由 Rails 负责,不涉及需要 SEO 页面间跳转的操作都是单页应用。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号