pushState 和 SEO

IT技术 javascript web-applications seo hashbang pushstate
2021-03-09 11:10:02

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

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

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

因此,场景是:

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

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

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

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

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

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

3个回答

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

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

你说:

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

所以换句话说,

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

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

那么谷歌将如何看待 pushState 的任何事情呢?

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

实际上,Google 会在site.com/blog. URL 仍然指向服务器上的资源,客户端仍然遵守这个约定。当然,对于现代客户而言,Javascript 开辟了无需刷新页面即可检索内容和与内容交互的新可能性,但契约是相同的。

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

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

  1. Facebook 方法——在 URLsite.com/blog提供相同的内容,当您推/blog送到状态时,您的客户端应用程序将转换为该 URL (据pushState我所知,Facebook 还没有使用,但他们用 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,view-source 和 reload 都将从新 URI 获取内容。”)

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

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

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

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

如果我有一个像: 的链接<a href="product/productName" onclick="showProduct(product)">A product</a>,并且 onclick 以“ preventDefault()开头,那么 AJAXly 将关于产品的新内容加载到页面中,并且我确保链接“.../product/productName”将加载一个版本的特定产品内容将包含在来自服务器的响应中的页面 --- 因此,该站点仍将动态工作,但通过直接转到产品链接,仍然可以使用静态内容,对吗?不需要以这种方式使用 pushState 或 hashbang,不是吗?
2021-04-29 11:10:02
@Harry - 你读过我的其余答案了吗?URL 是一个 URL - 意味着一个资源定位器。服务器是否相信内容存在于site.com/blog如果没有,那么它对搜索引擎不存在。的目的pushState不是解决这个问题。是为了方便。Hashbangs 也不能解决这个问题,它_escaped_fragment_是一种复杂的解决方法,它仍然依赖于服务器具有JS 生成内容快照(普通用户可以看到,正如你所说)。 pushState实际上简化了这一切。
2021-05-03 11:10:02
@Harry - 在 URL 被设计为服务客户端内容之前,它们仍然引用服务器上的资源,客户端会这样对待它们,包括机器人。这并不意味着您在客户端上做尽可能多的目标是无效的,但就目前而言,它可能必须使用(丑陋的)hashbangs 来完成。我已经为您的用例更新了我的答案。
2021-05-08 11:10:02
@Harry 首先,我只是不了解 Google 所说的他们所做的事情_escaped_fragment_,我不知道您具体做了什么。但是从 Google 所说的来看,我假设当您看到该查询参数时,您必须通过服务器提供某种内容在您的情况下,它需要一些技巧,但您可以提供一些<noscript>内容或其他内容/blog,然后让 JS 构建您想要的页面。或者,您可以尝试检测机器人并有意提供完全不同的内容。
2021-05-10 11:10:02
再一次,正确和最好的答案没有被选为正确的……糟糕,糟糕。
2021-05-10 11:10:02

使用 Google 为那些不希望在其 URL 中使用 hash-bangs 的人推荐的元标记怎么样: <meta name="fragment" content="!">

请参阅此处了解更多信息:https : //developers.google.com/webmasters/ajax-crawling/docs/getting-started

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

您对您建议的解决方案的体验如何?Google 是否将这个“临时”HTML 编入索引?它是否在相关的谷歌搜索中正确显​​示?也不是说体验有点“紧张”,因为初始 HTML 页面是用 JS 生成的 html“刷新”的?
2021-04-23 11:10:02
@NileshKale以下是我整理了一下解决方案,它完成的工作非常好:stackoverflow.com/questions/22824991/...我只是传递一个 HTML 表和 jqgrid 与 JSON 等价物(HTML 中的内容)。SEO 读取 HTML,用户通过 ajax 获得升级的体验和所有后续请求。使用 pushstate,我可以根据用户对网格进行排序/分页的方式更新 URL(不需要 hashbang)。这允许用户保存 URL 并返回相同的结果。
2021-04-24 11:10:02
几天后我会尝试对我的答案进行编辑以更好地解释。
2021-04-27 11:10:02
现在的AJAX抓取方案已经过时:developers.google.com/webmasters/ajax-crawling/docs/...建议更换使用它的网站:plus.google.com/+JohnMueller/posts/LT4fU7kFB8W
2021-05-09 11:10:02
@NickC,好的,我明白了,所以现在我认为更好的解决方案是在没有任何 JS 的情况下最初显示内容。但是在你的 JS 的顶部(在页面加载和 dom 准备好之后)立即运行一些代码来隐藏最初显示的 HTML 内容或用 JS 增强替换它。例如,我使用jquery datagrids,所以我会先显示一个HTML表格,然后立即加载JS来转换/隐藏/替换显示到JS网格版本的普通表格数据。然后从那时起,任何其他 ajax 请求都可以作为 JSON 与通过 pushstate 更新的 URL 配对。
2021-05-12 11:10:02

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

我们的解决方案是使我们的 99% 基于 JavaScript 的 Ajax 站点/应用程序可搜索引擎优化#!由于客户端渲染是通过 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 版本的任何内容。对于不可搜索引擎优化的内容(例如只有在用户登录后才能看到的页面),不需要存在 PHP 版本。一切都很简单。

我仍然感到困惑的是,一些前端开发人员如何在不将服务器端技术与浏览器技术结合使用的情况下开发出色的网站(具有丰富的 Google Docs)...如果没有 PHP,当然不会做任何事情。

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

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