哪一个更好的pushstate或location.hash?

时间:2012-02-18 09:37:48

标签: ajax html5 url

window.location.hash vs HTML5 history.pushstate。使用ajax请求满足url哪个更好,为什么? 感谢。

9 个答案:

答案 0 :(得分:28)

location.hashhistory.pushState方法有更好的支持 pushState方法的优点是您可以将状态绑定到历史记录条目 如果您不需要此状态对象,我建议使用location.hash属性,以便与旧版浏览器更好地兼容。

location.hash = 'new-hash';
console.log(history.state); // null or undefined

history.pushState({extraData: "some state info"}, '', 'new-hash'); //<---
console.log(history.state); // [object Object] = {"extraData": "some state info"}

答案 1 :(得分:24)

Pushstate是未来。它更好,因为:

  1. 看起来更干净。
  2. 重新访问深层链接,您实际上可以显示真实的服务器端数据,以支持搜索引擎优化和Facebook Open Graph等内容(两者都会发送蜘蛛来抓取您网页的HTML)。
  3. 服务器无权访问哈希标记数据,因此您不会在服务器日志中看到它,因此它可以帮助某些人进行分析。
  4. 它有助于修复哈希标记问题。例如,我进行了Nginx重写,将访问我的应用的用户重定向到相同的https网址。它适用于所有浏览器,但Safari会将您重定向到没有哈希的域(非常烦人)!
  5. 您实际上可以使用哈希标记来实现目的,深层链接到长页面的部分。
  6. 您可以回退使用不支持推送状态的浏览器的真实HTTP后端请求,或者您可以回退到使用哈希标记。两者都需要额外的实施,但只需要做一点工作就可以轻松完成。
  7. 请参阅Github设计师的演讲,了解更多信息:http://warpspire.com/talks/responsive/

答案 2 :(得分:13)

history.pushState优于location.hash。但它是HTML5功能。所以总是更好地拥有如下所述的后备方法。

if (typeof(window.history.pushState) == 'function') {
    window.history.pushState(null, path, path);
} else {
    window.location.hash = '#!' + path;
}

答案 3 :(得分:8)

我同意其他答案,但这里有一些论据支持 location.hash

  • 适用于所有浏览器,包括Internet Exploder TM
  • history.pushState是一个开发标准,API可能会在将来发生变化
  • 如果用户在新窗口/选项卡中打开链接,则哈希URL确保加载页面不需要服务器请求(如果设置了正确的缓存头)
  • 服务器配置很简单,因为所有服务器都看到的是没有哈希部分的URL

编辑:我忘了一个

  • 使用主题标签,您可以使用真实链接(a href)。因此,您不必设置单击侦听器,从而提高性能并减少代码大小。

答案 4 :(得分:7)

window.location.hash与HTML5 history.pushstate的优缺点很大程度上取决于您希望页面降级的程度。

在这里,您可能会对两种不同场景中的优雅降级感兴趣:

第一个是没有启用javascript的客户端,或者访问您网站的自动机器人/抓取工具。从SEO的角度来看,这一点尤为重要。如果您的网页/网络应用程序使用哈希网址,则这些最终用户无法使用通过这些链接提供的内容。如果您只通过没有回退的hash-url创建内容部分,这肯定是一个问题。但是,如果您使用哈希标记链接来修改应用程序状态,如果页面降级则不会保留意义,那么这绝对不是问题。

作为一个示例,请考虑一个场景,其中您在一个选项卡式布局窗口小部件中的三个选项卡中有一个包含三个文本部分的页面。现在有两种可能的情况:在第一种情况下,您将在页面加载期间加载所有内容 - 而选项卡式窗口小部件将仅用于隐藏其他部分并显示特定部分。因此,如果您在用于构建选项卡拇指的链接中使用hash-urls,则仅使用它们来更改客户端应用程序状态。当javascript被关闭/不可用时,只是用于构建选项卡式布局的javascript不会运行,并且所有内容都立即可用 - 一个合理的优雅后备。在这种情况下,不同的应用程序状态根本不存在,因此hash-urls会降级为仅指向html中的锚点 - 预期目的。 如果你在这种情况下使用html5 pushstate而不是hash-urls,那将是一个坏主意。用户可能将链接添加到特定选项卡的链接的原因。因为您的服务器必须获取该URL并向用户显示他期望的客户端状态。这对于瘦客户端应该处理自己的状态管理的瘦服务器体系结构来说并不好。您可以在服务器端忽略该方面,让客户端在页面加载时检查URL,然后切换到适当的应用程序状态。但它仍然不是一个好主意,因为你的服务器端路由系统关注它应该忽略的额外url片段的开销,因为从美学的角度来看它根本不应该被打扰。这完全映射到设计hash-urls的要求,强烈建议使用它们。如果在三个部分中,当单击特定选项卡缩略图时动态加载文本,则使用hash-url不是一个好主意。原因是如果javascript不可用,用户将无法访问链接的内容。这对SEO来说特别糟糕。在这种情况下,如果您处理服务器端的URL(在正常情况下会被“劫持”和“ajaxified”)以使内容一般可用,从最终用户体验和SEO的角度来看它都是极好的。

第二种情况是客户端拥有一个不支持html5 pushstates的过时浏览器。虽然以上几点仍然有效,但我还认为强迫没有pushstate的用户具有与no-javascript相同的降级水平是不合理的。很多最终用户根本不知道他们为什么会收到降级版本。

我建议你不要随意使用最新技术的教条,并为你的使用场景决定最佳选择。

答案 5 :(得分:5)

这是一个相当陈旧的问题(在回复时为5年+)但是对现有回复的很多评论都要求基于&#34;当前&#34;事态。

这是这笔交易:

所有主流浏览器都支持HTML5的pushState。如果您也支持较旧的浏览器,history.js提供了一个很好的polyfill,它允许您本机使用pushState并让它轻松回退到旧浏览器的旧URL。现在说pushState是原生支持的,但并不意味着它绝对是最佳选择。

在任何较旧的答案中都没有提出一个非常重要的观点,那就是散列URL和pushState URL不仅在它们出现的方式上有所不同,而且它们的工作方式实际上也有所不同。 。两者之间的这种根本区别可能会导致您选择一个而不是另一个。

pushState更漂亮,更清洁,可用于完全伪造您网站/应用中的导航。例如,GitHub使用它来无形地替换所有导航。当您单击其站点上的任何链接时,javascript用于拦截该单击并将其转换为AJAX请求,该请求更新页面内容而不加载新页面,而位置栏中的URL更改为与内容相匹配牵强。 这就是pushState用于的原因。

在GitHub的案例中,http://mysite/page1http://mysite/page2都是有效的网址。他们是真实的&#34;链接&#34;真实&#34;内容,并且最初访问任一页面都是通过传统的MVC方法。 GitHub在现代浏览器中使用pushState进行导航,但不需要它 - 即pushState用作&#34;功能添加&#34; (在他们看来)在导航方面可以带来更好的用户体验。当您复制浏览器地址栏中的链接时,您正在复制通过javascript&amp; amp; pushState,但是一个真实有效的链接。

但是,如果您从抓取并创建单个页面应用程序开始并且未使用MVC框架,则可能实际上只有一个页面,特别是如果您没有使用动态后端(即内容全部是通过javascript检索,从未由服务器生成)。在这种情况下,如果您使用pushState而不是哈希URL,则需要处理浏览器中的URL不是真实URL的情况。我会说明一下。

用户加载您的单页应用:http://mysite/mainpage

此时,浏览器栏包含指向您应用的真实链接,并将用户带到他们当前看到的相同视图:主页面。现在,他们点击一个链接,将他们带到&#34;页面&#34;显示某些活动的详细信息。此时,您需要更新位置栏以指示状态的更改。您使用的是哈希网址,而您的位置栏看起来像http://mysite/mainpage#charts/1,或者您使用pushState并诱骗它成为http://mysite/mainpage/charts/1

如果您使用的是pushState,则不是真正的链接。通过浏览器的后退/前进按钮导航将很有效,用户将从主页面转到位置栏和应用程序中的详细信息页面(假设您正确处理状态更改),但如果用户为此链接添加书签或复制并粘贴链接以进行共享,将需要额外的服务器端伏都教。

您需要将请求重定向到/ mainpage / charts / 1到/ mainpage,然后使用JS解析实际的URL并执行预期的状态更改操作。绝对需要服务器重定向。如果没有可编写脚本的http服务器,则无法在AWS或本地磁盘上托管此页面。

现在,如果你使用了哈希网址,那么用户可能已经看到并与之互动的网址就是http://mysite/mainpage#/charts/1 ,这是一个有效的真实网址。浏览器明白只有一个页面,无论用户是复制还是粘贴链接还是书签,你只需要在javascript中处理哈希状态,并且不需要任何服务器端魔法来使事情有效。

似乎没有人提到的是 pushState和hash链接不是互斥的。 pushState只是一个API,用于操纵用户可见的浏览器位置,并在现代浏览器中实现可靠的后退/前进导航。它没有说明你的URL方案应该是什么样的。

2017年,谷歌和几乎所有其他支持JS的机器人都能理解哈希网址,并且可以很好地遍历它们。谷歌希望你使用#! SEO的憎恶 最大化的目的,但即使你没有,你的网站也可以正常导航。

正确的答案是使用最符合您需求的任何东西。如果您有真正的URL并想要伪造它们之间的导航,请使用pushState并继续(可选择使用旧版浏览器的polyfill)。但是,如果你有一个单页应用程序,不要假装没有(除非你有一个很好的理由)。使用哈希URL可以让您的生活更轻松,不会引入不必要的问题,然后使用pushState来操纵这些哈希URL,以利用更好的后退/前进支持

答案 6 :(得分:2)

我个人更喜欢pushState,因为它可以生成更好看的网址,而且我认为这对用户体验非常重要。

如果您想使用pushState,则可以使用history.js polyfill使用history.pushState哈希回退,但不希望出现旧浏览器支持问题。

答案 7 :(得分:2)

目前,所有现代浏览器都支持pushState。因此pushState优于location.hash,但它是HTML5功能。

所以,location.hash并没有死,事实上它将会存在很长很长时间。

使用它的一个好方法是使用支持pushState的lib,但也可以优雅地降级为使用location.hash
示例 - https://github.com/browserstate/history.js

此外location.hash对于跳转到命名锚点仍然有用。 pushState将为构建网络应用提供巨大帮助。我期待着使用它。

答案 8 :(得分:0)

我在此线程中的任何地方都没有看到一个非常小的差异:

设置 window.location.hash 将强制立即滚动跳转到文档中的新哈希元素(至少在我拥有的浏览器中)。如果您想要平滑滚动但又希望更新/更改 url 栏中的哈希值,则必须像这样使用 window.history.pushState

document.getElementById(id).scrollIntoView({ behavior: "smooth" });
window.history.pushState(null, null, "#" + id);