82

很多人一直在说,使用 pushState 而不是 hashbang。

我不明白的是,如果不使用 hashbang,您将如何对搜索引擎友好?

大概您的 pushState 内容是由客户端 JavaScript 代码生成的。

因此,情况是:

我在example.com。我的用户点击一个链接:href="example.com/blog"

pushState 捕获点击,更新 URL,从某处获取 JSON 文件,并在内容区域创建博客文章列表。

使用 hashbangs,谷歌知道去 escaped_fragment URL 来获取他们的静态内容。

使用 pushState,Google 什么也看不到,因为它不能使用 JavaScript 代码加载 JSON 并随后创建模板。

我可以看到的唯一方法是在服务器端呈现模板,但这完全否定了将应用程序层推送到客户端的好处。

所以我说对了吗,pushState 对客户端应用程序根本不友好吗?

4

3 回答 3

98

如果您需要搜索引擎来阅读您的内容,这很pushState糟糕吗?

不,讨论pushState是围绕完成与 hashbangs 相同的一般过程,但具有更好看的 URL。想想当你使用 hashbang 时会发生什么……

你说:

使用 hashbangs,Google 知道去 escaped_fragment URL 来获取他们的静态内容。

所以换句话说,

  1. 谷歌看到一个链接example.com/#!/blog
  2. 谷歌请求example.com/?_escaped_fragment_=/blog
  3. 返回用户应该看到的内容的快照

如您所见,它已经依赖于服务器。 如果您没有从服务器提供内容的快照,那么您的网站没有被正确编入索引。

那么谷歌将如何看待 pushState 呢?

使用 pushState,谷歌什么也看不到,因为它不能使用 javascript 来加载 json 并随后创建模板。

实际上,谷歌会看到它可以请求的任何内容site.com/blog。URL 仍然指向服务器上的资源,客户端仍然遵守这个约定。当然,对于现代客户来说,Javascript 为在不刷新页面的情况下检索和交互内容开辟了新的可能性,但合同是相同的。

因此,预期的优雅之处pushState在于,它为所有用户提供相同的内容,无论新旧、支持 JS 还是不支持 JS,但新用户获得了增强的体验

你如何让谷歌看到你的内容?

  1. Facebook 方法 — 在 URLsite.com/blog上提供相同的内容,当您推送到状态时,您的客户端应用程序将转换为/blog。(据我所知,Facebook 还没有使用pushState,但他们使用 hashbangs 来做到这一点)

  2. Twitter 方法——将所有传入的 URL 重定向到等效的 hashbang。换句话说,指向“/b​​log”的链接会推/blog送到状态。但如果直接请求,浏览器会以#!/blog. (对于 Googlebot,这将路由到_escaped_fragment_您想要的位置。对于其他客户端,您可以pushState返回到漂亮的 URL)。

所以你失去了_escaped_fragment_能力pushState吗?

在几个不同的评论中,你说

转义片段完全不同。您可以提供纯非主题内容、缓存内容,而不会像普通页面那样承受负载。

理想的解决方案是 Google 要么创建 JavaScript 站点,要么实现某种方式来知道即使对于 pushstate 站点(robots.txt?)也存在转义的片段 URL。

你提到的好处并不是孤立的_escaped_fragment_。它为您进行重写并使用特殊命名的GET参数实际上是一个实现细节。没有什么特别之处是您无法使用标准 URL 完成的——换句话说,您/blog可以/?content=/blog使用mod_rewrite或您的服务器的等效项自行重写。

如果您根本不提供服务器端内容怎么办?

如果您无法重写 URL 并在(或您推送到浏览器中的任何状态)提供某种内容/blog,那么您的服务器实际上不再遵守 HTTP 合同。

这很重要,因为页面重新加载(无论出于何种原因)将在此 URL 处提取内容。(请参阅https://wiki.mozilla.org/Firefox_3.6/PushState_Security_Review —“如果推送了新 URI,则查看源和重新加载都将获取新 URI 的内容。”)

并不是说在客户端绘制用户界面并通过 JS API 加载内容是一个糟糕的目标,它只是没有真正考虑到 HTTP 和 URL,而且它基本上不向后兼容。

目前,这正是 hashbang 的用途——表示在客户端而不是服务器上导航的不同页面状态。例如,重新加载将加载相同的资源,然后该资源可以读取、解析和处理散列值。

恰好它们也被用于(尤其是 Facebook 和 Twitter)将历史记录更改为服务器端位置而无需刷新页面。 正是在这些用例中,人们建议为 pushState 放弃 hashbang。

如果您在客户端呈现所有内容,您应该将其pushState视为更方便的历史 API 的一部分,而不是使用 hashbangs 的出路。

于 2011-05-31T22:49:05.070 回答
17

对于那些不想在 URL 中使用 hash-bangs 的人来说,使用 Google 建议的元标记怎么样: <meta name="fragment" content="!">

有关更多信息,请参见此处: https ://developers.google.com/webmasters/ajax-crawling/docs/getting-started

不幸的是,我认为 Nicole 没有澄清我认为 OP 遇到的问题。问题很简单,如果我们不使用 hash-bang,我们就不知道我们向谁提供内容。Pushstate 并没有为我们解决这个问题。我们不希望搜索引擎告诉最终用户导航到一些会输出未格式化 JSON 的 URL。相反,我们创建通过 AJAX 检索数据并以我们喜欢的方式将其呈现给用户的 URL(触发对更多 URL 的其他调用)。如果用户不是人类,那么作为替代方案,我们可以提供一个 html 快照,以便搜索引擎可以正确地将人类用户引导到他们希望在该 URL 上找到请求的数据(并且以一种可呈现的方式)。但最终的挑战是我们如何确定用户类型?是的,我们可以使用 . htaccess 或其他东西来重写我们检测到的搜索引擎机器人的 URL,但我不确定这是多么全面和面向未来。谷歌也有可能会惩罚做这种事情的人,但我还没有完全研究过。所以(pushstate + google's meta tag)组合似乎是一个可能的解决方案。

于 2012-09-06T02:51:24.990 回答
2

所有关于 pushState 和 的有趣讨论#!,我仍然看不到 pushState 如何取代 #! 的目的,正如原始海报所要求的那样。

我们使 99% 基于 JavaScript 的 Ajax 站点/应用程序可 SEO 的解决方案#!当然是在使用。由于客户端渲染是通过 HTML、JavaScript 和 PHP 完成的,我们在由我们的页面登陆控制的加载器中使用以下逻辑。HTML 文件与 JavaScript 和 PHP 完全分离,因为我们希望两者都使用相同的 HTML(大部分情况下)。JavaScript 和 PHP 做的事情基本相同,但 PHP 代码不那么复杂,因为 JavaScript 提供了更丰富的用户体验。

JavaScript 使用 jQuery 将它想要的内容注入 HTML。PHP 使用 PHPQuery 将它想要的内容注入 HTML - 使用“几乎”相同的逻辑,但更简单,因为 PHP 版本将仅用于显示带有 SEOable 链接的 SEOable 版本,而不像 JavaScript 版本那样进行交互。

所有这些都是组成页面的三个组件,page.htm、page.js 和 page.php 存在于任何使用转义片段来知道是否加载 PHP 版本而不是 JavaScript 版本的东西。对于非 SEOable 内容(例如只有在用户登录后才能看到的页面),不需要存在 PHP 版本。一切都很简单。

我仍然对一些前端开发人员如何在不使用服务器端技术和浏览器技术的情况下开发出色的网站(利用 Google Docs 的丰富性)感到困惑......如果甚至没有启用 JavaScript,那么我们的 99% JavaScript 解决方案如果没有 PHP,当然不会做任何事情。

如果启用了 JavaScript,则可以有一个不错的 URL 登陆 PHP 提供的页面并重定向到 JavaScript 版本,但从用户的角度来看这并不好,因为用户是更重要的受众。

在旁注中。如果您只是制作一个无需任何 JavaScript 即可运行的简单网站,那么如果您想逐步将用户体验从简单的静态渲染内容提升为更好的内容,那么我可以看到 pushState 很有用,但是如果您想为用户提供随时随地获得最佳体验...假设您用 JavaScript 或类似 Google Docs 编写的最新游戏,那么它用于此解决方案的方式有些限制,因为与愿景相比,优雅后退只能走这么远,用户体验会很痛苦的网站。

于 2016-05-31T08:05:25.990 回答