使用新 URL 更新地址栏(不带哈希值)或重新加载页面 [duplicate]

Updating address bar with new URL without hash or reloading the page [duplicate]

提问人:David Murdoch 提问时间:7/27/2010 最后编辑:CommunityDavid Murdoch 更新时间:2/8/2022 访问量:563769

问:

我要么梦想着 chrome(开发频道)实现一种通过 javascript(路径,而不是域)更新地址栏而无需重新加载页面的方法,要么他们真的做到了这一点。

但是,我找不到我认为我读过的文章。

我是疯了还是有办法做到这一点(在 Chrome 中)?

p.s. 我不是在谈论 window.location.hash 等。如果存在上述情况,这个问题的答案将是不正确的。

JavaScript 阿贾克斯 Google-Chrome

评论

3赞 David Murdoch 8/24/2016
@tobiaskienzler 当这个问题最初在2009年被问到时,这是不可能的。
8赞 Tobias Kienzler 8/24/2016
当然不是。但现在是这样,问题也要求同样的问题。可惜的是,另一个人接受了一个过时的答案(我注意到了你)......你知道吗?反过来说,没有人说“原版”一定是旧的,其实是有先例的
0赞 David Murdoch 8/24/2016
@tobiaskienzler,另一个问题没有一个过时的公认答案。
0赞 Tobias Kienzler 8/24/2016
好吧,不是过时,但更复杂。尽管如此,这两个问题对我来说似乎几乎是一样的,但也许我在这里遗漏了一个细微差别......
3赞 Imam Assidiqqi 12/24/2016
@TobiasKienzler这是一个 6 年前的问题,你为什么要为这个问题而烦恼?只需享受惊人的答案并在您的应用程序上实施它。6 年来,成千上万的 SO 用户一致认为这是一个了不起的问题,请保持原样。

答:

986赞 David Murdoch 7/27/2010 #1

您现在可以在大多数“现代”浏览器中执行此操作!

这是我读到的原始文章(发布于 2010 年 7 月 10 日):HTML5:在不刷新页面的情况下更改浏览器 URL

要更深入地了解 pushState/replaceState/popstate(又名 HTML5 历史 API),请参阅 MDN 文档

TL的;DR,您可以执行以下操作:

window.history.pushState("object or string", "Title", "/new-url");

请参阅我的回答 在不重新加载页面的情况下修改 URL,了解基本操作方法。

评论

3赞 oldestlivingboy 7/27/2010
啊,该功能在 WebKit 中,几个月前登陆 <bugs.webkit.org/show_bug.cgi?id=36152>。不错的发现!
0赞 Zach Lysobey 12/20/2011
现在可以在 Chrome、Safari、FF4+ 和 IE10pp3+ 中完成!(摘自大卫·默多克对 stackoverflow.com/questions/824349/ 的回答...... )
15赞 Mahn 8/3/2013
提示:您也可以将相对路径与这些函数一起使用(例如 或。他们似乎至少在Chrome中做了你所期望的。../new-url../../new-url
6赞 Kos 7/31/2016
我想补充一点,这更容易设置,而且通常更可取,例如,当您想在用户更改某些下拉列表或搜索字段的值后更新 URL 时。如果要使用 ,那么还需要正确支持 event。window.replaceStatepushStateonpopstate
1赞 David Murdoch 3/26/2020
@fwzard .该对象是一个 JavaScript 对象,它与 创建的新历史记录条目相关联。每当用户导航到 new 时,都会触发一个事件,并且该事件的属性包含历史记录条目对象的副本。对象可以是任何可以序列化的内容。所以它实际上不仅仅是.文档:developer.mozilla.org/en-US/docs/Web/API/History/pushStatestatestatepushState()statepopstatestatestatestate"object or string"
198赞 Pawel 9/2/2016 #2

仅更改哈希之后的内容 - 旧浏览器

document.location.hash = 'lookAtMeNow';

更改完整 URL。Chrome、Firefox、IE10+

history.pushState('data to be passed', 'Title of the page', '/test');

上面将在历史记录中添加一个新条目,因此您可以按“返回”按钮转到以前的状态。若要更改原位 URL,而不向历史记录添加新条目,请使用

history.replaceState('data to be passed', 'Title of the page', '/test');

立即尝试在控制台中运行这些!

评论

20赞 Choylton B. Higginbottom 9/22/2016
replaceState这正是我需要的,感谢您扩展原始回复。
1赞 Rick 9/26/2017
“域名和协议必须与原始内容相同!” 这样可以防止某些钓鱼网站更改地址栏 URL。
3赞 DimeCadmium 6/17/2018
不应将绝对 URL 传递给此函数。如果你这样做,你很可能需要从当前的方案、主机和端口动态构建它——当你可以把它变成一个相对的URL(“foo.html”甚至“/foo.html”)并让浏览器处理它时,这是很多工作。
1赞 Pawel 6/18/2018
@DimeCadmium很好的简化。更新。
0赞 azzamsa 1/26/2019
history.replaceState添加到FF 66.0B1的历史
37赞 metamagikum 7/4/2017 #3

更新了 Davids 答案,甚至可以检测不支持 pushstate 的浏览器

if (history.pushState) {
  window.history.pushState(stateObj, "title", "url");
} else {
  window.history.replaceState(stateObj, "title**", 'url');
  // ** It seems that current browsers other than Safari don't support pushState
  // title attribute. We can achieve the same thing by setting it in JS.
  document.title = "Title";
}

状态Obj

state 对象是一个 JavaScript 对象,它与传递给 replaceState 方法的历史记录条目相关联。state 对象可以为 null。

标题

大多数浏览器目前都忽略了这个参数,尽管它们将来可能会使用它。在此处传递空字符串应该是安全的,不会将来对方法进行更改。或者,您可以传递该州的简短头衔。

url 可选

历史记录条目的 URL。新 URL 必须与当前 URL 的来源相同;否则 replaceState 将引发异常。

评论

25赞 paullb 7/29/2017
document.location.href 重新加载页面
1赞 Kafaa Billahi Syahida 5/19/2022
嗯,我看到了Caniuse(pushstatereplacestate)的兼容性,两者都是相同的,它不支持旧浏览器
18赞 Kevin Mendez 3/4/2020 #4
var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?foo=bar';
window.history.pushState({path:newurl},'',newurl);

评论

11赞 Maximouse 3/4/2020
虽然此代码片段可能会解决问题,但包含解释确实有助于提高帖子的质量。请记住,您将来正在为读者回答问题,而这些人可能不知道您提出代码建议的原因。
0赞 Kevin Mendez 4/19/2020
@MaxiMouse感谢您的帮助,我会牢记在心的。
4赞 11/16/2020
建议编辑:const url = new URL(window.location);url.searchParams.set('foo', 'bar');window.history.pushState({}, '', url);