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


2376

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

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

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

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

139
为了使问题更容易理解,例如,这是Facebook打开照片时的行为。网址栏会更改为直接指向该照片,因此您可以共享URL而不会丢失您在网站中的位置。还记得过去十年基于框架的网站吗?您只能获取首页网址,因为只有内部框架在更改。那太可怕了。
Spidey

虽然history.pushState()这可能是正确的答案,但是在这种情况下(取决于具体情况...),您可能需要考虑使用服务器端重定向(例如通过使用Apache的RewriteRule指令)的可能性,或者至少意识到。只是认为应该提到!
杜安

Answers:


2031

现在,可以在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文章


272
然后,Facebook如何在IE7中做到这一点?
多米尼克

57
@CHiRiLo签出history.js,它为不支持HTML5历史记录API的浏览器提供后备功能。
大卫·默多克

23
@infensus如果URL中的某处有一个#号,则该技巧已存在多年 ..
Izkata 2012年

34
“ IE10pp4 +”的“ pp4 +”部分是什么意思?
Scott Tesler

34
平台预览4
David Murdoch

585

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

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

这里了解更多


12
可能无法正常工作在file:///为安全起见,如火狐30的测试localhostpython -m SimpleHTTPServer
Ciro Santilli冠状病毒审查六四事件法轮功

6
第一个参数应该是一个对象,而不仅仅是一个字符串。
Alexis Wilke

39
IMO这确实是最好的答案。如果您要做的就是更新当前URL({},null,strNewPath),则只需要做。最好先测试if(history.pushState){}
Craig Jacobs

7
如果您不想更改前两个参数,则只需输入null。您也可以为第三个参数使用绝对URL。
安德鲁(Andrew)

3
如果您在答案中输入更多信息,那就太好了。我不知道参数1会做什么。
RedClover

129

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

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

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


108

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

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

1
最好先使用if(history.pushState){}进行测试,以防万一旧的浏览器。
Craig Jacobs

在Firefox中您将无法再使用此功能:操作不安全。
kkatusic,2017年

106

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

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

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


33
我不想更改域,仅更改路径和文件名。
TheFlash

5
这仍然不能阻止潜在的安全风险,因为浏览器不知道用户将域/ mysite和域/ othersite都视为“安全”。也许问题应该是您为什么要更改URL?如果要让用户看不到它,则可以简单地在iframe中运行应用程序。
罗宾·

5
您实际上可以使用Flash进行此操作。它将允许您修改URL而无需发出请求。这是可能的,因为Flash在浏览器外部运行,但与浏览器紧密相关。
Nick Berardi

142
我不得不说有完全正当的理由想要修改地址栏客户端中的URL。例如,如果您有一个具有分页,排序和过滤功能的数据表,并希望这些功能受Ajax支持,但仍要更新URL,以便该页面的当前状态可添加书签。我可以通过修改域名(网络钓鱼等)来理解安全隐患,但是为什么浏览器不允许仅通过脚本修改顶级域名右侧的一部分URL?
星期日铁脚

41
这个答案不再是100%正确的。请参阅我的答案以获取详细信息。
大卫·默多克

83
parent.location.hash = "hello";

15
我想更改URL,而不仅仅是散列-
TheFlash

42
更改哈希值在ajax中很有用,因为它是一种不使用cookie的状态,可以添加书签,并且与浏览器后退按钮兼容。Gmail如今已使用它来使其对浏览器更加友好。
马修·洛克

@贾维斯:有什么区别?

@noisy服务器端跟踪无法看到哈希,除非将其显式发送到跟踪服务。
RedYetiCo 2014年

如果您使用的是在散列上路由的mvc框架(例如主干),则此功能将无用。
catbadger'2

27

在现代浏览器和HTML5中,有一种称为pushStatewindow 的方法history。这将更改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');

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

更改#非常容易,例如:

window.location.hash = "example";

您可以像这样检测到它:

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

window.onhashchangewindow.onpopstate做在这种情况下一样吗?
J0ANMM

如何加载页面内容?它只是替换URL
MD。Atiqur Ra​​hman

像通常使用ajax一样加载内容。
AndroidDev


24

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

parent.location.hash = "hello";

和:

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

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


2
问题history.pushState(..)在于,如果您要重定向到另一个域,则跨域策略将生效。虽然可以window.location.replace(..)重定向到另一个域。
OSWorX

23

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

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


17

以下是无需重新加载页面即可更改URL的功能。仅HTML5支持。

  function ChangeUrl(page, url) {
        if (typeof (history.pushState) != "undefined") {
            var obj = {Page: page, Url: url};
            history.pushState(obj, obj.Page, obj.Url);
        } else {
            window.location.href = "homePage";
            // alert("Browser does not support HTML5.");
        }
    }

  ChangeUrl('Page1', 'homePage');

2
@Green,页面是您要移至的状态的简短标题。Firefox当前会忽略此参数,尽管将来可能会使用它。在此处传递空字符串应该可以防止将来对方法的更改。来自:developer.mozilla.org/en-US/docs/Web/API/…–
Snook,

13

如果您不只是更改URL片段,则对位置的任何更改(window.locationdocument.location)都将导致对该新URL的请求。如果更改URL,则更改URL。

如果您不喜欢当前使用的URL,请使用服务器端URL重写技术,例如Apache的mod_rewrite


我可以使用“ location.pathname”吗?
TheFlash

3
不,更改该属性也会引起请求。
浓汤

11

您可以添加锚标记。我在网站上使用它,以便可以通过Google Analytics(分析)跟踪页面上正在访问的人。

我只添加一个锚标记,然后添加我要跟踪的页面部分:

var trackCode = "/#" + urlencode($("myDiv").text());
window.location.href = "http://www.piano-chords.net" + trackCode;
pageTracker._trackPageview(trackCode);

9

正如Thomas Stjernegaard Jeppesen指出的那样,您可以使用History.js在用户浏览Ajax链接和应用程序时修改URL参数。

自从该答案以来,已经过去了将近一年的时间,History.js变得更加稳定和跨浏览器。现在,它可用于管理HTML5兼容的以及许多仅HTML4的浏览器中的历史记录状态。在此演示中,您可以看到一个示例其工作方式(以及可以尝试其功​​能和限制的示例)。

如果您在如何使用和实现该库方面需要任何帮助,我建议您看一下演示页面的源代码:您会发现它很容易做到。

最后,要全面了解使用散列(和哈希爆炸)可能存在的问题,请查看Benjamin Lupton的此链接



7

您可以使用此漂亮而简单的功能在应用程序中的任何地方使用。

function changeurl(url, title) {
    var new_url = '/' + url;
    window.history.pushState('data', 'Title', new_url);
    document.title = title;
}

您不仅可以编辑URL,还可以同时更新标题。

对每个人都非常有帮助。


1
即使对于锚也像魅力一样工作window.history.pushState('data', 'Title', '#new_location');
BIOHAZARD
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.