题 修改URL而不重新加载页面


有没有办法在不重新加载页面的情况下修改当前页面的URL?

我想访问该部分 之前 #hash如果可能的话。

我只需要改变部分  域名,所以它不像我违反跨域政策。

 window.location.href = "www.mysite.com/page2.php";  // sadly this reloads

1810
2018-05-05 10:54


起源


您可以在Flash中执行此操作。您只需要一个后台应用程序,并将您的JavaScript传递给Flash以修改位置栏。 - Nick Berardi
只是为了更容易理解这个问题,这就是Facebook打开照片时所做的事情。网址栏会更改为直接指向该照片,因此您可以共享该网址而不会丢失您在网站中的位置。记住基于过去十年框架的网站?你只能获得主页网址,因为只有内部框架在变化。这太可怕了。 - Spidey


答案:


现在可以在Chrome,Safari,FF4 +和IE10pp4 +中完成!

有关详细信息,请参阅此问题的答案: 使用新URL更新地址栏,不使用哈希或重新加载页面

例:

 function processAjaxData(response, urlPath){
     document.getElementById("content").innerHTML = response.html;
     document.title = response.pageTitle;
     window.history.pushState({"html":response.html,"pageTitle":response.pageTitle},"", urlPath);
 }

然后你可以使用 window.onpopstate 检测后退/前进按钮导航:

window.onpopstate = function(e){
    if(e.state){
        document.getElementById("content").innerHTML = e.state.html;
        document.title = e.state.pageTitle;
    }
};

有关操纵浏览器历史的更深入了解,请参阅 这篇MDN文章


1633
2017-07-28 15:30



facebook如何在IE7中完成呢? - Dominic Tobias
@CHiRiLo退房 history.js 这为不支持HTML5历史记录API的浏览器提供了后备。 - David Murdoch
@infensus如果在某个地方有一个#符号,这个技巧已经存在了 年份.. - Izkata
“IE10pp4 +”的“pp4 +”部分是什么意思? - Scott David Tesler
平台预览4 - David Murdoch


HTML5介绍了 history.pushState() 和 history.replaceState() 方法,允许您分别添加和修改历史记录条目。

window.history.pushState('page2', 'Title', '/page2.php');

从中了解更多相关信息 这里


382
2017-08-17 13:59



可能无法继续工作 file:/// 出于安全原因,例如Firefox 30.测试 localhost 同 python -m SimpleHTTPServer。 - Ciro Santilli 新疆改造中心 六四事件 法轮功
我在codeigniter上使用了这个。 - jned29
第一个参数应该是一个对象,而不仅仅是一个字符串。 - Alexis Wilke
IMO这是最好的答案。如果你想要做的就是更新当前的URL({},null,strNewPath)就是你需要做的。最好先使用if(history.pushState){}进行测试 - Craig Jacobs
如果您不想更改它们,您可以为前2个参数输入null。您还可以使用绝对URL作为第三个参数。 - Andrew


注意:如果您正在使用 HTML5 浏览器然后你应该忽略这个答案。现在可以在其他答案中看到这一点。

没有办法修改 URL 在浏览器中没有重新加载页面。 URL表示上次加载的页面的内容。如果你改变它(document.location)然后它将重新加载页面。

一个显而易见的原因是,你写了一个网站 www.mysite.com 看起来像银行登录页面。然后你改变浏览器的URL栏来说 www.mybank.com。用户将完全不知道他们真的在看 www.mysite.com


96
2018-05-05 10:57



我不想更改域,只需要更改路径和文件名。 - Robinicks
这仍然不能阻止潜在的安全风险,因为浏览器不知道域/ mysite和域/ otherite都被用户认为是“安全的”。也许问题应该是为什么要更改URL?如果要将其与用户混淆,只需在iframe中运行您的应用程序即可。 - Robin Day
你可以用Flash实际做到这一点。它允许您在不发出请求的情况下修改URL。这是可能的,因为Flash在浏览器之外运行,但与之紧密相关。 - Nick Berardi
我不得不说,想要修改地址栏客户端的URL是完全正确的理由。例如,如果您有一个包含分页,排序和过滤的数据表,并希望这些内容是基于Ajax的,但仍然更新URL,以便页面的当前状态是可收藏的。我可以通过修改域名(网络钓鱼等)来理解安全风险,但为什么浏览器不允许只通过脚本修改顶级域右侧的URL部分? - Sunday Ironfoot
这个答案不再是100%真实。详情请见我的回答。 - David Murdoch


您也可以使用HTML5 replaceState 如果要更改URL但不想将条目添加到浏览器历史记录中:

if (window.history.replaceState) {
   //prevents browser from storing history with each change:
   window.history.replaceState(statedata, title, url);
}

这将“打破”后退按钮功能。在某些情况下可能需要这样做,例如图像库(您希望后退按钮返回到图库索引页面而不是向后移动您查看的每个图像),同时为每个图像提供其自己唯一的URL。


93
2017-11-19 10:32





parent.location.hash = "hello";

73
2018-05-13 22:14



我想更改URL,而不仅仅是哈希 - #mydata - Robinicks
更改哈希在ajax中很有用,因为它是一种不使用cookie的状态,可收藏,并且与浏览器后退按钮兼容。 Gmail现在使用它来使其更适合浏览器。 - Matthew Lock
@Jarvis:有什么区别? - noisy
@noisy服务器端跟踪无法看到哈希,除非明确发送到跟踪服务。 - RedYetiCo
如果你使用的是一个在哈希上路由的mvc框架,例如主干,这没用。 - catbadger


这是我的解决方案:( newUrl是你想要替换当前新url的新url)

history.pushState({}, null, newUrl);

45
2018-06-10 18:25



最好先测试if(history.pushState){}以防万一旧浏览器。 - Craig Jacobs
这在Firefox中不再适用:操作不安全。 - kkatusic


正如Vivart和geo1701已经提到的那样,HTML5 replaceState就是答案。但是并非所有浏览器/版本都支持它。 History.js 包装HTML5状态功能并为HTML4浏览器提供额外支持。


25
2017-11-21 11:09





在HTML5之前我们可以使用:

parent.location.hash = "hello";

和:

window.location.replace("http:www.example.com");

此方法将重新加载您的页面,但HTML5引入了 history.pushState(page, caption, replace_url) 不应重新加载您的页面。


20
2018-01-24 08:49



这个问题 history.pushState(..) 是,如果要重定向到另一个域,则跨域策略生效。与...同时 window.location.replace(..)可以重定向到另一个域。 - OSWorX


如果您要做的是允许用户书签/共享页面,并且您不需要它是完全正确的URL,并且您没有使用哈希锚点来处理其他任何内容,那么您可以在两个中执行此操作部分;您使用上面讨论的location.hash,然后在主页上实现检查,以查找其中包含哈希锚的URL,并将您重定向到后续结果。

例如:

1)用户已开启 www.site.com/section/page/4

2)用户执行一些将URL更改为的操作 www.site.com/#/section/page/6 (用哈希)。假设您已将第6页的正确内容加载到页面中,因此除了哈希之外,用户不会受到太多干扰。

3)用户将此URL传递给其他人,或对其进行书签

4)其他人,或以后的同一用户,去 www.site.com/#/section/page/6

5)代码 www.site.com/ 将用户重定向到 www.site.com/section/page/6,使用这样的东西:

if (window.location.hash.length > 0){ 
   window.location = window.location.hash.substring(1);
}

希望有道理!对于某些情况,这是一种有用的方法。


18
2018-04-19 11:43





该位置的任何变化(或者 window.location 要么 document.location)如果您不仅仅是更改URL片段,将会对该新URL发出请求。如果更改URL,则更改URL。

使用服务器端URL重写技术 Apache的mod_rewrite 如果您不喜欢您当前使用的网址。


12
2018-05-05 10:58



我可以使用“location.pathname”吗? - Robinicks
不,更改该属性也会导致请求。 - Gumbo