如何在不重新加载页面的情况下修改 URL?

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

如果可能,我想访问#哈希之前的部分。

我只需要更改域的部分,所以就好像我没有违反跨域策略一样。

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

答案

现在,可以在 Chrome,Safari,Firefox 4 + 和 Internet Explorer 10pp4 + 中完成此操作!

有关更多信息,请参见此问题的答案: 使用新 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 文章

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

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

这里了解更多

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

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

这将 “破坏” 后退按钮的功能。在某些情况下可能需要这样做,例如图库(您希望后退按钮返回到图库索引页面,而不是在浏览的每个图像中都回退),同时为每个图像提供自己的唯一网址。

注意:如果使用的是 HTML5 浏览器,则应忽略此答案。如其他答案所示,现在这是可能的。

如果不重新加载页面,则无法在浏览器中修改URL 。该 URL 代表上一次加载的页面。如果您更改它( document.location ),它将重新加载页面。

一个明显的原因是,您在www.mysite.com上写了一个看起来像银行登录页面的网站。然后,将浏览器 URL 栏更改为www.mybank.com 。用户将完全不知道他们真的在访问www.mysite.com

这是我的解决方案(newUrl 是您要用当前 URL 替换的新 URL):

history.pushState({}, null, newUrl);
parent.location.hash = "hello";

如 Vivart 和 geo1701 所述,HTML5 replaceState 是答案。但是,并非所有浏览器 / 版本都支持该功能。 History.js包装了 HTML5 状态功能,并为 HTML4 浏览器提供了额外的支持。

在现代浏览器和 HTML5 中 ,窗口history有一种称为pushState的方法。这将更改 URL 并将其推入历史记录而不加载页面。

您可以像这样使用它,它将使用 3 个参数,1)状态对象 2)标题和 URL):

window.history.pushState({page: "another"}, "another page", "example.html");

这将更改 URL,但不会重新加载页面。另外,它不会检查页面是否存在,因此,如果您执行一些可响应 URL 的 JavaScript 代码,则可以像这样使用它们。

另外还有history.replaceState()可以做完全相同的事情,除了它将修改当前历史记录而不是创建新历史记录!

您还可以创建一个函数来检查history.pushState存在,然后像下面这样进行处理:

function goTo(page, title, url) {
  if ("undefined" !== typeof history.pushState) {
    history.pushState({page: page}, title, url);
  } else {
    window.location.assign(url);
  }
}

goTo("another page", "example", 'example.html');

您还可以更改<HTML5 browsers# ,这将不会重新加载页面。这就是 Angular 根据标签使用SPA的方式...

更改#相当容易,就像这样:

window.location.hash = "example";

您可以像这样检测到它:

window.onhashchange = function () {
  console.log("#changed", window.location.hash);
}

在 HTML5 之前,我们可以使用:

parent.location.hash = "hello";

和:

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

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

如果您要允许用户添加书签 / 共享页面,而又不需要它是完全正确的 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);
}

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