关于 AJAX 的常见问题解答

在 AJAX 网址中何时应使用 _escaped_fragment_ 以及何时应使用 #!

您的网站应该对所有采用 AJAX 抓取机制的网址使用 #! 语法。Googlebot 不会跟踪 _escaped_fragment_ 格式的超链接。

哪里有此机制的应用示例?

您可以访问 http://gwt.google.com/samples/Showcase/Showcase.html 查看 AJAX 应用示例。点击左侧的任意链接后,您都会看到相应网址包含一个 #! 哈希代码段,并且该应用会转到此哈希代码段对应的状态。如果您将 #!(例如 http://gwt.google.com/samples/Showcase/Showcase.html#!CwRadioButton)更改为 ?_escaped_fragment_=(例如 http://gwt.google.com/samples/Showcase/Showcase.html?_escaped_fragment_=CwRadioButton),网站将返回 HTML 快照。

如果我选择不在我的 AJAX 网站上使用 #!,会怎样?

如果您这样做的话,您的网页近期内可能无法在 Google 搜索结果页中正常显示。不过,我们一直在不断改进 Googlebot,设法使其运行方式更像浏览器。届时,当您在自己的网站上实施所需的功能后,Googlebot 可能会自动将您的网页正确编入索引。但是,对于已使用 AJAX 且希望现在可以确保将内容正确编入索引的网站而言,此 AJAX 抓取机制是一个非常实用的解决方案。我们期望此解决方案可以有效解决其网页已有 HTML 快照的用户的问题,或者解决那些使用无头浏览器获取此类 HTML 快照的用户的问题。

内容应多久更新一次?

这完全取决于应用内容的更新频率。如果更新很频繁,您应该及时构建最新的 HTML 快照以响应抓取工具请求。如果不频繁,可以考虑创建归档库,存放不进行定期更新的内容。为了避免让服务器不断生成相同的 HTML 快照,您可以一次性创建所有相关 HTML 快照(可能离线),然后保存以备将来参考。您还可以使用 304(未修改)HTTP 状态代码来响应 Googlebot。

如果我的应用没有使用哈希代码段,会怎样?

我们建议您使用!使用哈希代码段,可以明显地加快应用响应速度,因为哈希代码段由客户端的浏览器进行处理,不会导致整个网页都需要刷新。此外,哈希代码段还支持在应用中提供历史记录(也就是备受诟病的“浏览器后退按钮”)。各种 AJAX 框架都支持哈希代码段。例如,请参阅 Really Simple History、jQuery 的历史记录插件、Google Web Toolkit 的历史记录机制,或 ASP.NET AJAX 对历史记录管理的支持。

不过,如果应用无法使用哈希代码段,您可以执行以下操作,在哈希代码段(即网址中 # 标记之后的所有内容)中使用特殊令牌。代表唯一网页状态的哈希代码段必须以感叹号开头。例如,如果 AJAX 应用包含像下面这样的网址:

www.example.com/ajax.html#mystate

现在它应变为如下形式:

www.example.com/ajax.html#!mystate

如果您的网站采用该机制,将被视为“AJAX 可抓取”。这意味着,如果您的网站提供 HTML 快照,抓取工具将会看到您的应用的内容。

这种方法会导致“不美观的”_escaped_fragment_ 网址越来越多吗?

网址的 _escaped_fragment_ 语法对应的是临时网址,绝不应该被最终用户看到。在用户可看到的所有环境中,包括常规应用交互、站点地图、超链接、重定向,以及用户可能会看到网址的其他任何情况,都应该使用“美观的网址”(带有 #! 而不是 _escaped_fragment_)。出于相同的原因,搜索结果均为“美观的网址”,而不是“不美观的网址”。

使用此机制会导致“伪装真实内容”问题吗?

隐藏真实内容指为用户提供的内容与为搜索引擎提供的内容不同,这通常是为了提高网页在搜索结果中的排名。伪装真实内容过去一直是(将来也会一直是)一个重要的搜索引擎问题,因此请务必注意,将 AJAX 应用设置为可抓取,绝不是为了给伪装真实内容提供方便。因此,HTML 快照包含的内容必须与最终用户在浏览器中看到的内容相同。如果不相同,则可能会被视为伪装真实内容。请参阅具体解答了解详情。

可以使用此机制来让我的 Flash 或其他富媒体文件更容易抓取吗?

Google 确实能将许多富媒体文件类型编入索引,而且在持续努力改进抓取和索引编制。但是,Googlebot 可能并不能看到 Flash 或其他富媒体应用的所有内容(正如它无法抓取您网站上的所有动态内容一样),因此,使用此机制可以向 Googlebot 提供更多内容。此外,HTML 快照包含的内容必须与最终用户在浏览器中看到的内容相同。Google 有权从索引中排除被视为隐藏真实内容的网站。

如果我的网站包含一些不想被抓取的哈希代码段网址,该怎么办?

如果您的网站采用 AJAX 抓取机制,Google 抓取工具会抓取它遇到的每个哈希代码段网址。如果您不想让某些哈希代码段网址被抓取,建议您在 robots.txt 文件中添加一个正则表达式指令。例如,您可以在不应被抓取的哈希代码段中使用某种惯例形式,然后在 robots.txt 文件中排除符合该惯例的所有网址。假设所有表示不可编入索引的状态都采用 #DONOTCRAWLmyfragment 形式,那么您可以向 robots.txt 中添加以下代码,阻止 Googlebot 抓取这些网页:

Disallow: /*_escaped_fragment_=DONOTCRAWL

如何处理哈希代码段中已有的 #!

#! 是现有哈希代码段中不常用的令牌;但是网址规范并没有规定不能使用它。如果您的应用使用了 #!,但是不想采用新的 AJAX 抓取机制,该怎么办?有一种方法是在 robots.txt 中添加以下指令,以指示抓取工具如何处理。

Disallow: /*_escaped_fragment_

请注意,这表示如果您的应用只包含网址 www.example.com/index.html#!mystate,则该网址不会被抓取。如果您的应用还包含纯网址 www.example.com/ajax.html,则该网址会被抓取。

对无障碍功能有何影响?

为搜索引擎提供静态内容的现行方法有一个附带的作用,即网站所有者可以让残障用户更方便地访问其应用。此新协议进一步完善了无障碍功能:网站所有者不再需要手动干预,即可使用无头浏览器创建 HTML 快照,其中包含所有相关内容并可供屏幕阅读器使用。这意味着,现在可以更轻松地提供最新的静态内容,手动工作越来越少。也就是说,网站所有者现在会更愿意构建方便残障用户使用的应用。

应该如何使用 rel="canonical"

请使用 <link rel="canonical" href="http://example.com/ajax.html#!foo=123" />,不要使用 <link rel="canonical" href="http://example.com/ajax.html?_escaped_fragment_=foo=123" />

我应该将哪个网址添加到站点地图中?

您应该在站点地图中添加您希望显示在搜索结果中的网址,因此应添加 http://example.com/ajax.html#!foo=123

#! 的网址会对商品 Feed 产生什么影响?

网站通常希望在 Google 购物和 Google 网页搜索中显示相同的网址。通常,应将带 #! 的网址视为可用于任何环境的“规范”版本,而将 _escaped_fragment_ 网址视为始终都不应让最终用户看到的临时网址。

我使用 HtmlUnit 作为无头浏览器,它却不起作用。这是为什么?

如果“不起作用”表示 HtmlUnit 没有返回您希望看到的快照,则很可能是由于您未给予足够的时间供它执行 JavaScript 和/或 XHR 请求。若要解决这个问题,请尝试执行以下任意或全部操作:

  • 使用 NicelyResynchronizingAJAXController。这样可以指示 HtmlUnit 等待所有未完成的 XHR 调用执行完毕。
  • 增加 waitForBackgroundJavaScript 和/或 waitForBackgroundJavaScriptStartingBefore 的等待时间。

这在大多数情况下都可以解决问题。如果问题仍然存在,您还可以查阅有关 HtmlUnit 的常见问题解答,网址为:http://htmlunit.sourceforge.net/faq.html。HtmlUnit 还设有用户论坛。