PushState 和 SEO

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

我不明白的是,如果不使用 hashbang,你怎么能对搜索引擎友好呢?

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

情况是这样的:

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

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

使用 hashbang,google 知道访问转义 _ 片段 URL 来获得它们的静态内容。

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

我认为唯一的方法是在服务器端呈现模板,但这完全抵消了将应用程序层推给客户端的好处。

那么我说的对吗,pushState 对于客户端应用程序来说并不是 SEO 友好的?

22477 次浏览

如果你需要搜索引擎来阅读你的内容,pushState是坏的吗?

不,关于 pushState的讨论是围绕完成同样的 hashbang 的一般过程,但是使用更好看的 URL。想想当你用散列的时候会发生什么。

你说:

通过 hashbang,Google 知道访问转义 _ 片段 URL 来获得它们的静态内容。

换句话说,

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

如您所见,它已经依赖于服务器

那么 Google 将如何看待 pushState 呢?

对于 pushState,Google 什么也看不到,因为它无法使用 JavaScript 加载 JSON 并随后创建模板。

事实上,谷歌会在 site.example/blog上看到它可以请求的任何东西。URL 仍然指向服务器上的资源,客户端仍然遵守此协议。当然,对于现代客户机,JavaScript 为在不刷新 呼叫的情况下检索内容和与内容交互提供了新的可能性,但是协议是相同的。

因此,pushState的优雅之处在于它为所有用户提供相同的内容,无论是新用户还是老用户,支持 JS 的用户还是不支持 JS 的用户,而是新用户 获得更好的体验

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

  1. Facebook 的方法ーー在 URL site.example/blog上提供与您的客户端应用程序在将 /blog推入状态时转换成的内容相同的内容。(据我所知,Facebook 还没有使用 pushState,但是他们使用了 hashbang)

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

那么你是否失去了 pushState_escaped_fragment_能力?

在一些不同的评论中,你说

逃逸的碎片完全不同。您可以提供纯粹的非主题化内容、缓存内容,而不必像普通页面那样承受负载。

The ideal solution is for Google to either do JavaScript sites or implement some way of knowing that there's an escaped fragment URL even for pushstate sites (robots.txt?).

你所提到的好处并不仅限于 _escaped_fragment_。它为您执行重写并使用一个特别命名的 GET参数实际上是一个实现细节。没有什么特别的地方是标准 URL 无法做到的ーー换句话说,使用 改写或服务器的等价物自己将 /blog重写为 /?content=/blog

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

如果您不能重写 URL 并在 /blog(或者任何您推入浏览器的状态)下为 某种内容提供服务,那么您的服务器实际上不再遵守 HTTP 协议。

这一点很重要,因为页面重新加载(不管出于什么原因)将在这个 URL 上提取内容

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

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

它只是碰巧是他们有 也被使用过(特别是由 Facebook 和 Twitter)改变历史记录到一个服务器端的位置,而不需要刷新页面。正是在这些用例中,人们建议为 pushState 放弃 hashbang。

如果在客户端呈现所有内容,那么应该将 pushState视为更方便的历史 API 的一部分,而不是使用 hashbang 的方法。

谷歌建议那些不想在自己的网址中添加杂凑符号的人使用 meta 标签,这种做法怎么样: <meta name="fragment" content="!">

更多信息请点击这里: Https://developers.google.com/webmasters/ajax-crawling/docs/getting-started

不幸的是,我认为妮可并没有澄清我认为观察所存在的问题。问题很简单,如果不使用 hash-bang,我们就不知道要向谁提供内容。Pushstate 不能为我们解决这个问题。我们不希望搜索引擎告诉终端用户导航到某个 URL,从而导出未格式化的 JSON。相反,我们创建通过 AJAX 检索数据并以我们喜欢的方式向用户显示数据的 URL (这会触发对更多 URL 的其他调用)。如果用户不是人类,那么作为一个替代方案,我们可以提供 html 快照,这样搜索引擎可以正确地将人类用户引导到他们希望在(并以可见的方式)找到所请求数据的 URL。但最大的挑战是我们如何确定用户的类型?是的,我们可以利用。我们检测到的搜索引擎机器人可以通过 htaccess 或者其他方式重写 URL,但是我不确定这是否完全可靠。也有可能谷歌会因为人们做这样的事情而惩罚他们,但是我还没有对此进行充分的研究。所以(pushstate + google 的 meta 标签)组合似乎是一个可能的解决方案。

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

我们的解决方案,使我们的99% 基于 JavaScript 的 Ajax 站点/应用程序 SEOable 当然是使用 #!。由于客户端渲染是通过 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 或类似谷歌文档,然后这个解决方案的使用是有限的,因为优雅的后退只能到这一步,用户体验是痛苦的相比,网站的愿景。