我看到AngularJS应用程序关于搜索引擎和SEO的两个问题:

1)自定义标签会发生什么?搜索引擎会忽略这些标签中的全部内容吗?例如,假设我有

<custom>
  <h1>Hey, this title is important</h1>
</custom>

<h1>是否在自定义标记中被索引?

2)有没有办法避免搜索引擎索引{{}}绑定字面上?即。

<h2>{{title}}</h2>

我知道我可以做点什么

<h2 ng-bind="title"></h2>

但是如果我真的想让爬虫“看到”标题呢?服务器端渲染是唯一的解决方案吗?


当前回答

自从提出这个问题以来,情况已经发生了很大的变化。现在有一些选项可以让谷歌索引你的AngularJS站点。我发现最简单的选择是使用http://prerender.io的免费服务,它会为你生成可抓取的页面,并将其提供给搜索引擎。几乎所有服务器端web平台都支持它。我最近开始使用它们,支持也很好。

我和他们没有任何关系,这是来自一个快乐的用户。

其他回答

在这里可以找到一个好的实践:

http://scotch.io/tutorials/javascript/angularjs-seo-with-prerender-io?_escaped_fragment_=tag

这种情况已经发生了巨大的变化。

http://searchengineland.com/bing-offers-recommendations-for-seo-friendly-ajax-suggests-html5-pushstate-152946

如果你使用: 美元locationProvider.html5Mode(真正的); 你准备好了。

不再有渲染页面。

(2022)尽可能使用服务器端渲染,并使用Pushstate生成url

谷歌现在可以运行JavaScript,所以很可能只使用JavaScript构建一个网站,只要你创建一个合理的URL结构。然而,页面速度已经成为一个越来越重要的排名因素,通常客户端构建的页面在初始渲染时表现不佳。

服务器端呈现(SSR)可以帮助您在服务器上预先生成页面。你的html包含将被用作页面根的div,但这不是一个空的div,它包含JavaScript将生成的html,如果它被允许运行。

客户端下载HTML并渲染它,给出一个非常快速的初始加载,然后执行JavaScript,用生成的内容替换根div的内容,这个过程称为水合作用。

许多新的框架都内置了SSR,尤其是NextJS。

(2015)使用PushState和Precomposition

目前(2015年)的方法是使用JavaScript的pushState方法。

PushState在不重新加载页面的情况下更改浏览器顶部栏中的URL。假设您有一个包含选项卡的页面。选项卡隐藏和显示内容,内容是动态插入的,可以使用AJAX,也可以简单地设置display:none和display:block来隐藏和显示正确的选项卡内容。

当单击选项卡时,使用pushState更新地址栏中的URL。呈现页面时,使用地址栏中的值确定要显示哪个选项卡。Angular的路由会自动为你做这件事。

Precomposition

有两种方法可以点击推送状态单页应用(SPA)

通过PushState,用户点击一个PushState链接,内容就被ajax化了。 通过直接点击URL。

在网站上的初始点击将包括直接点击URL。当PushState更新URL时,后续的点击将简单地在内容中加入AJAX。

爬虫从页面中获取链接,然后将它们添加到队列中以供后续处理。这意味着对于爬虫来说,服务器上的每一次点击都是直接点击,它们不通过Pushstate导航。

预组合将初始有效负载捆绑到来自服务器的第一个响应中,可能是作为JSON对象。这允许搜索引擎在不执行AJAX调用的情况下呈现页面。

有一些证据表明谷歌可能不会执行AJAX请求。更多信息请点击这里:

https://web.archive.org/web/20160318211223/http://www.analog-ni.co/precomposing-a-spa-may-become-the-holy-grail-to-seo

搜索引擎可以读取和执行JavaScript

谷歌已经能够解析JavaScript有一段时间了,这就是为什么他们最初开发了Chrome,作为谷歌蜘蛛的全功能无头浏览器。如果一个链接有一个有效的href属性,新的URL可以被索引。没什么可做的了。

如果另外点击一个链接触发一个pushState调用,用户可以通过pushState来导航站点。

搜索引擎支持PushState url

推送状态目前由谷歌和必应支持。

谷歌

以下是Matt Cutts对Paul Irish关于PushState在SEO方面的问题的回答:

http://youtu.be/yiAF9VdvRPw

下面是谷歌宣布对蜘蛛的完全JavaScript支持:

http://googlewebmastercentral.blogspot.de/2014/05/understanding-web-pages-better.html

结果是谷歌支持PushState并将索引PushState url。

参见谷歌网站管理员工具的fetch as Googlebot。你会看到你的JavaScript(包括Angular)被执行了。

Bing

以下是必应在2013年3月宣布支持漂亮的PushState url:

http://blogs.bing.com/webmaster/2013/03/21/search-engine-optimization-best-practices-for-ajax-urls/

不要使用hashbang #!

Hashbang url是一种丑陋的权宜之计,要求开发人员在特定位置提供网站的预渲染版本。它们仍然有效,但你不需要使用它们。

Hashbang url是这样的:

domain.example / # !/ /资源路径

这将与一个像这样的元标签配对:

<meta name="fragment" content="!" >

谷歌不会以这种形式对它们进行索引,而是从escaped_fragments URL中提取站点的静态版本并对其进行索引。

Pushstate URL看起来像任何普通的URL:

domain.example /道路/ /资源

不同之处在于,Angular会通过拦截对文档的更改来为你处理它们。location用JavaScript处理它。

如果你想使用PushState url(你可能会这样做),去掉所有旧的散列样式的url和元标签,在配置块中启用HTML5模式。

测试你的网站

谷歌网站管理员工具现在包含一个工具,它将允许您获取谷歌的URL,并呈现JavaScript作为谷歌呈现它。

https://www.google.com/webmasters/tools/googlebot-fetch

在Angular中生成PushState url

要在Angular中生成真实的url,而不是带有#前缀的url,请在$locationProvider对象上设置HTML5模式。

$locationProvider.html5Mode(true);

服务器端

由于您使用的是真实url,因此需要确保服务器为所有有效url提供相同的模板(加上一些预先组合的内容)。如何做到这一点取决于您的服务器架构。

网站地图

你的应用程序可能会使用不寻常的导航形式,例如悬停或滚动。为了确保谷歌能够驱动你的应用程序,我可能会建议创建一个站点地图,一个你的应用程序响应的所有url的简单列表。你可以把它放在默认位置(/sitemap或/sitemap.xml),或者使用网站管理员工具告诉谷歌。

无论如何,有一个站点地图是个好主意。

浏览器支持

Pushstate在IE10中工作。在旧的浏览器中,Angular会自动退回到哈希样式的url

演示页面

下面的内容是使用预合成的推送状态URL渲染的:

http://html5.gingerhost.com/london

正如可以验证的那样,在这个链接中,内容被编入索引,并出现在谷歌中。

提供404和301报头状态码

因为搜索引擎总是会为每个请求访问您的服务器,所以您可以从服务器提供报头状态代码,并期望谷歌看到它们。

Angular自己的网站为搜索引擎提供简化的内容:http://docs.angularjs.org/?_escaped_fragment_=/tutorial/step_09

假设你的Angular应用正在使用一个Node.js/ express驱动的JSON api,比如/api/path/to/resource。也许您可以使用?_escaped_fragment_将任何请求重定向到/api/path/to/resource.html,并使用内容协商来呈现内容的HTML模板,而不是返回JSON数据。

唯一的问题是,你的Angular路由需要与你的REST API 1:1匹配。

编辑:我意识到这有可能真正搅乱你的REST api,我不建议在非常简单的用例之外使用它,在那里它可能是一个自然的适合。

相反,您可以为机器人友好的内容使用完全不同的路由和控制器集。但是你在Node/Express中复制了所有AngularJS的路由和控制器。

我决定用无头浏览器生成快照,尽管我觉得这有点不太理想。

爬虫不需要一个功能丰富的漂亮的图形用户界面,他们只想看到内容,所以你不需要给他们一个已经为人类构建的页面的快照。

我的解决方案:给爬虫程序想要的东西:

你必须考虑爬虫者想要什么,只给他那个。

小贴士:不要弄脏后面。只需使用相同的API添加一点服务器端前视图