AngularJS 社交分享和 SEO






4.25/5 (3投票s)
随着 Web 应用程序开发越来越依赖 JavaScript 技术(AngularJS、React 等),对 JavaScript 渲染的依赖变得比以往任何时候都更加重要。本文将介绍如何在纯 JavaScript 应用程序中处理 SEO 和社交分享。
问题
AngularJS 框架非常棒,双向数据绑定是 AngularJS 的主要特性和强大之处之一。在我开始从事我的 AngularJS 项目的第一天,我就无法回头了。
这种 JavaScript 渲染 HTML 的技术非常棒,与 ASP.Net MVC 等其他框架相比,它更简单、更快速。
但是,一个问题始终在我脑海中盘旋——当我们不需要浏览器就能获取最终渲染的页面(包括所有内容和元标签)时会发生什么?比如说,通过 Web 请求?或者某个爬虫?结果会是什么?
在下面的 POC 示例应用程序中,我创建了一个带有简单服务的 Angular 应用程序,该服务会更新 rootScope 上的 **MetaTitle** 和 **MetaDescription** 值,并将它们绑定到 title 和 description 元标签。
angular.module('MyApp',[]).service('updatemymetaplease',function($rootScope){ var $rootScope = $rootScope; retrun { UpdateNow: function(title,description) { this.$rootScope.MetaTitle = title; this.$rootScope.MetaDescription = description; } }}) .controller('MainController',function(updatemymetaplease){ updatemymetaplease.UpdateNow('My App Title','Awsome Application'); });
以及 page.html 文件
<html ng-app="MyApp"> <head> <title>{{MetaTitle}}</title> <meta name="description" content="{{ MetaDescription }}"> </head> <body ng-controller="MainController"> <p>Exemple App</p> <script src="app.js"></script> </body> </html>
在 Angular 的 digest 周期之后,输出将如下所示
<html> <head> <title>My App Title</title> <meta name="description" content="Awsome Application"> </head> <body></body> <script src="app.js"></script> </html>
是不是很棒?没有静态元标签,我的 HTML 文件完全是动态的、干净且易于阅读,没有任何难以理解的 JS 文件和全局作用域上的 JQuery 操作,尤其是——我不需要任何服务器端框架(asp.net、php、java 等),我可以在客户端动态绑定我的元标签。
让我们来测试一下我们超赞的网站的 Facebook 分享预览框吧!
- Facebook 预览显示
为什么?
嗯,JavaScript 是一种客户端语言(NodeJS 系列除外)。我的意思是 UI 只能由浏览器运行和渲染——那么如果你的客户端不使用浏览器会发生什么?在这种情况下,Facebook 抓取器——爬虫期望获得一个完全渲染的 HTML 页面,实际上调用者似乎进行了 GET 请求,返回了以下 HTML 页面。
<html> <head> <title>{{MetaTitle}}</title> <meta name="description" content="{{ MetaDescription }}"> </head> <body> <p>Exemple App</p> </body> </html>
这不是 Bug!
我们都知道 Google 开始渲染重度 JS 应用程序,这为 Google SEO 问题提供了解决方案,但对于 Bing 爬虫呢?Facebook 抓取器?Twitter 和许多其他服务?此时,一个纯 AngularJS 应用将会显示出它作为输出 HTML 的样子,而没有 JS 渲染。
我真的必须用服务器端框架来包装我的应用程序来解决这个问题吗?——**不**
解决方案描述
我们将使用超棒的 PhantomJS (http://phantomjs.org/) 在发送响应之前渲染 AngularJS 脚本,这样我们就可以确保元标签和内容对搜索引擎可用,并且 HTML 页面的输出将是完全渲染的 HTML 页面。您还可以设置一个快照创建器——这样您可以比以往更快地响应。
这将是应用程序的最终生命周期
一旦 IIS 收到一个传入的请求,Rewrite 模块就会决定
- 如果是 Facebook、Twitter、Bing 或您定义的任何内容——那么请求将被传输到 PhantomJS Windows 服务——并且完全渲染的 HTML 将是输出。
- 否则,将执行常规的网站行为。
确保您按照预期定义重写规则,不要将所有 HTTP 调用重定向到 PhantomJS,只重定向您需要的。
下载代码:https://github.com/benmizrahi/AngularJS-Social-Sharing-And-SEO
设置与配置
测试环境:Windows Server 2012 R2,IIS 8.5
步骤 1 - 安装
1) 下载并安装 URL-Rewrite 模块
http://www.iis.net/
2) 下载并安装 Application-Request-Routing
步骤 2 - Phantom Windows 服务
1) 下载 git 项目。
2) 打开 PhantomService.exe.config 文件,用记事本打开,配置以下内容:
a) PathToPhantom - phantom.exe 的本地路径(来自 zip)。
b) PhantomScript - phantom 脚本的本地路径(Components\phantomWS.js)。
c) PhantomLogLocation - phantom 日志记录位置
d) PhantomPort - 监听的本地端口
e) LocalHost - 你的本地应用主机(通常是 http://yourdnsname)。
f) CreateSnapshots - 启用快照(1/0)。
g) SanpshootLocation - 保存快照的位置。
3) 打开 cmd 并导航到 "C:\WINDOWS\Microsoft.NET\
4) 运行以下命令:InstallUtil.exe "\path\to\phantom\service\
5) 在启动 Windows 服务之前,请转到 "%systemroot%\system32\
打开 hosts 文件并将 yourdnsname 添加为 127.0.0.1 - 在服务器内部测试,您应该可以访问:
6) 转到“运行”并打开 services.msc, 启动 PhantomJSWS 服务,然后您可以通过浏览 https://:selectedport/ 来测试 phantom 是否正在运行 - 您应该会看到 IIS 欢迎屏幕。
步骤 3 - IIS 设置
Application Request Routing 配置
1) 打开 inetmgr,转到顶级(服务器级别)并选择 Features View。
2) 选择 Application Request Routing Catch (应该是第一个)。
3) 在右侧选择 Server Proxy Settings。
4) 勾选复选框 - Enable proxy。
5) 保存设置。
URL-Rewrite 配置
1) 打开 inetmgr,并选择您的站点或应用程序。
2) 在 Features View 中 - 选择 Url Rewrite
3) 添加以下设置
{ HTTP_USER_AGENT }
重写模型
URL:https://:selectedphantomport/
此设置会将请求重写到 phantom Windows 服务。
测试: 在 URL 中添加:?escaped_fragment_= 您应该会获得您请求的页面
示例: http://yourdnsname/?escaped_fragment_=。
步骤 4 - AngularJS 端
1) 将 RenderFinishedDirective.js 指令添加到您的站点并将其包含到您的 AngularApp 中。
2) 在您的 index.html 文件中 -> 在 body 元素的底部添加指令:
<render-finished-directive></
* 注意: 您可以通过在应用程序完成渲染时(所有 Promise 完成工作后)添加此代码来避免添加此指令。
if (typeof window.callPhantom == 'function') { window.callPhantom(); }
就是这样——您完成了。
如果您需要任何帮助,请随时联系。
Ben Mizrahi