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

Rob*_*cks 2221 html javascript url friendly-url url-rewriting

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

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

我只需要在域之后更改部分,因此它不像我违反了跨域策略.

 window.location.href = "www.mysite.com/page2.php";  // Sadly this reloads
Run Code Online (Sandbox Code Playgroud)

Dav*_*och 1925

现在可以在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);
 }
Run Code Online (Sandbox Code Playgroud)

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

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

有关操纵浏览器历史记录的更深入了解,请参阅此MDN文章.

  • facebook如何在IE7中完成呢? (262认同)
  • @CHiRiLo查看[history.js](https://github.com/balupton/History.js/),它为不支持HTML5历史记录API的浏览器提供后备. (53认同)
  • 平台预览4 (33认同)
  • "IE10pp4 +"的"pp4 +"部分是什么意思? (32认同)
  • @infensus如果在某个地方有一个#符号,这个技巧已经存在_years_ .. (21认同)
  • 请注意,OP 明确表示他们**不尝试导航到不同的来源**;“我并没有违反跨域政策。” -- 然而,我**正在尝试这样做,以及 [`window.history` API](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)不允许通过 `pushState` 进行跨域导航,(这是合理的......正如 Mozilla 网站所说,“新 URL 必须与当前 URL 具有相同的来源;否则,pushState() 将抛出异常。 ”) (12认同)
  • @ user2372006这里不太可能.试试[提问](http://stackoverflow.com/questions/ask). (4认同)
  • 应将哪些数据传递给“响应”? (3认同)
  • @manakor"现在可以在Chrome,Safari,FF4 +和IE10pp3 +中完成!" ......看起来会. (2认同)
  • `processAjaxData`只是一个例子; 它只是为了向您展示`history.pushState`的典型用例. (2认同)
  • 如何调用这个函数?我的意思是回应什么? (2认同)
  • 有什么回应? (2认同)

Viv*_*art 527

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

window.history.pushState('page2', 'Title', '/page2.php');
Run Code Online (Sandbox Code Playgroud)

这里了解更多相关信息

  • IMO这是最好的答案.如果你想要做的就是更新当前的URL({},null,strNewPath)就是你需要做的.最好先使用if(history.pushState){}进行测试 (35认同)
  • 出于安全原因,可能无法在`file:///`上工作,例如Firefox 30.使用`python -m SimpleHTTPServer`在`localhost`上测试. (11认同)
  • 第一个参数应该是一个对象,而不仅仅是一个字符串. (6认同)
  • 如果你不想改变它们,你可以为前2个参数输入null.您还可以使用绝对URL作为第三个参数. (5认同)
  • 很好的答案,还可以使用replaceState()更改当前历史记录而不是添加另一个历史记录;https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API#the_replacestate_method (3认同)
  • 如果您在答案中输入更多信息,那就太好了。我不知道参数1会做什么。 (2认同)
  • 我得到“无法在原点为“null”且 URL 为“file:///C:/Users/”的文档中创建 URL 为“file:///C:/Users/.../newUrl”的历史状态对象.../oldUrl.pdf'`。是因为它是本地磁盘 URL 吗? (2认同)

Geo*_*kos 120

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

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

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


Rob*_*Day 104

注意:如果您使用的是document.location浏览器,则应忽略此答案.现在可以在其他答案中看到这一点.

www.mysite.com没有重新加载页面就无法修改浏览器.URL表示上次加载的页面的内容.如果你改变它(www.mybank.com)那么它将重新加载页面.

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

  • 我不得不说想要修改地址栏客户端的URL是完全正确的理由.例如,如果您有一个包含分页,排序和过滤的数据表,并希望这些内容是基于Ajax的,但仍然更新URL,以便页面的当前状态是可收藏的.我可以通过修改域名(网络钓鱼等)来理解安全风险,但为什么浏览器不允许只通过脚本修改顶级域右侧的URL部分? (139认同)
  • 这个答案不再是100%真实.详情请见我的回答. (39认同)
  • 我不想更改域,只需要更改路径和文件名. (29认同)
  • 删除它或添加 html4,因为目前它在谷歌搜索中显示为快速答案 (8认同)
  • 这仍然不能阻止潜在的安全风险,因为浏览器不知道域/ mysite和域/ otherite都被用户认为是"安全的".也许问题应该是为什么要更改URL?如果要将其与用户混淆,您只需在iframe中运行应用程序即可. (4认同)
  • 你实际上可以用Flash做到这一点.它允许您在不发出请求的情况下修改URL.这是可能的,因为Flash在浏览器之外运行,但与它非常紧密. (4认同)
  • 用例确实在使用Ajax时,您可能会显示另一个文档但不想重新加载,但您希望文档可以加入书签.在这些情况下,人们希望在不更改域的情况下更改URL的路径,从安全角度来看,这应该没问题. (3认同)

Hai*_*mei 90

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

history.pushState({}, null, newUrl);
Run Code Online (Sandbox Code Playgroud)

  • 最好先使用 if (history.pushState) {} 进行测试,以防旧浏览器。 (6认同)

小智 81

parent.location.hash = "hello";
Run Code Online (Sandbox Code Playgroud)

  • 更改哈希在ajax中很有用,因为它是一种不使用cookie的状态,可收藏,并且与浏览器后退按钮兼容.Gmail现在使用它来使浏览器更友好. (40认同)
  • 我想更改URL,而不仅仅是哈希 - #mydata (13认同)
  • 这仅部分回答了问题。我们希望更改的是 url,而不是哈希值。 (2认同)

Tho*_*sen 25

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


Ali*_*eza 23

在现代浏览器和HTML5中,有一个名为pushStateon window 的方法history.这将更改URL并将其推送到历史记录而不加载页面.

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

window.history.pushState({page: "another"}, "another page", "example.html");
Run Code Online (Sandbox Code Playgroud)

这将更改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');
Run Code Online (Sandbox Code Playgroud)

你也可以改变history.pushStatefor #,这不会重新加载页面,这是根据hashtag <HTML5 browsers做的方式#...

改变pushState很容易,做得像:

window.location.hash = "example";
Run Code Online (Sandbox Code Playgroud)

你可以像这样检测它:

window.onhashchange = function () {
  console.log("#changed", window.location.hash);
}
Run Code Online (Sandbox Code Playgroud)

  • 像通常使用 ajax 一样加载内容。 (2认同)

Shi*_*ine 21

在HTML5之前我们可以使用:

parent.location.hash = "hello";
Run Code Online (Sandbox Code Playgroud)

和:

window.location.replace("http:www.example.com");
Run Code Online (Sandbox Code Playgroud)

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

  • “ history.pushState(..)”的问题在于,如果您想重定向到另一个域,则跨域策略生效。使用window.location.replace(..)重定向到另一个域是可能的。 (2认同)

Jer*_*rne 20

如果您要做的是允许用户书签/共享页面,并且您不需要它是完全正确的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);
}
Run Code Online (Sandbox Code Playgroud)

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


Sur*_*raj 14

以下是在不重新加载页面的情况下更改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');
Run Code Online (Sandbox Code Playgroud)

  • 什么是'page`? (4认同)
  • @Green,页面是您要移至的状态的简短标题。Firefox当前会忽略此参数,尽管将来可能会使用它。在此处传递空字符串应该可以防止将来对方法的更改。来自:https://developer.mozilla.org/zh-CN/docs/Web/API/History_API#The_pushState()_method (2认同)

Dhe*_*jje 14

您可以使用这个漂亮而简单的功能在您的应用程序的任何地方执行此操作。

function changeurl(url, title) {
    var new_url = '/' + url;
    window.history.pushState('data', title, new_url);
    
}
Run Code Online (Sandbox Code Playgroud)

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


Gum*_*mbo 12

如果您不仅仅是更改URL片段,那么对该位置的任何更改(window.location或者document.location)将导致对该新URL的请求.如果更改URL,则更改URL.

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

  • 不,更改该属性也会导致请求. (3认同)

小智 12

您可以添加锚标签.我在我的网站http://www.piano-chords.net/上使用此功能,以便我可以使用谷歌分析跟踪人们在页面上访问的内容.我只是添加一个锚标签,然后添加我要跟踪的页面部分.

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


Ere*_*Paz 8

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

从那个答案开始差不多一年了,History.js不断发展,变得更加稳定和跨浏览器.现在,它可以用于管理HTML5兼容的历史状态以及许多HTML4浏览器中的历史状态.在本演示中,您可以看到它的工作原理(以及能够尝试其功能和限制的示例).

如果您需要有关如何使用和实现此库的任何帮助,我建议您查看演示页面的源代码:您将看到它非常容易.

最后,有关使用哈希(和hashbangs)的问题的全面解释,请查看Benjamin Lupton的链接.


小智 7

使用history.pushState()从HTML 5 API的历史。

有关更多详细信息,请参考HTML5历史记录API


Vin*_*was 7

你的新网址。

let newUrlIS =  window.location.origin + '/user/profile/management';
Run Code Online (Sandbox Code Playgroud)

从某种意义上说,调用 pushState() 类似于设置 window.location = "#foo",两者都将创建和激活与当前文档关联的另一个历史条目。但是 pushState() 有几个优点:

history.pushState({}, null, newUrlIS);
Run Code Online (Sandbox Code Playgroud)

您可以查看根目录:https : //developer.mozilla.org/en-US/docs/Web/API/History_API

  • 请添加对 PushState 假定“优点”的引用:) (2认同)