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

How do I modify the URL without reloading the page?

提问人:Robin Rodricks 提问时间:5/5/2009 最后编辑:Web DeveloperRobin Rodricks 更新时间:4/24/2023 访问量:2030351

问:

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

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

我只需要更改域后面的部分,因此我不会违反跨域策略。

 window.location.href = "www.mysite.com/page2.php";  // this reloads
javascript html 重写 friendly-url

评论

186赞 Spidey 4/20/2012
只是为了更容易理解这个问题,例如,当您打开照片时,这就是 Facebook 所做的。网址栏更改为直接指向该照片,因此您可以共享网址,而不会丢失您在网站中的位置。还记得基于过去十年框架的网站吗?您只能获取主页网址,因为只有内部框架在更改。这太可怕了。
7赞 Doin 3/14/2020
虽然这里可能是正确的答案,但在这种情况下(取决于具体情况...),使用服务器端重定向(例如通过使用 Apache 的 RewriteRule 指令)的可能性是您可能需要考虑的,或者至少要注意。只是觉得应该提一下!history.pushState()
16赞 Ninjakannon 12/9/2021
window.history.replaceState(null, document.title, "/page2.php")大概是大多数人都在寻找的。

答:

119赞 Robin Day 5/5/2009 #1

注意:如果您使用的是 HTML5 浏览器,那么您应该忽略此答案。这现在是可能的,从其他答案中可以看出。

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

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

评论

8赞 Eugene 7/20/2021
删除它或添加 HTML4,因为目前它在 Google 搜索中显示为快速答案
13赞 Gumbo 5/5/2009 #2

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

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

评论

0赞 Robin Rodricks 5/5/2009
我可以使用“location.pathname”吗?
3赞 Gumbo 5/5/2009
否,更改该属性也会导致请求。
94赞 Steve 5/14/2009 #3
parent.location.hash = "hello";

评论

21赞 Robin Rodricks 5/15/2009
我想更改 URL,而不仅仅是哈希值 -- #mydata
43赞 Matthew Lock 11/24/2009
更改哈希值在 ajax 中很有用,因为它是一种不使用 cookie 的状态,可添加书签,并且与浏览器后退按钮兼容。Gmail 现在使用它来使其对浏览器更加友好。
0赞 noisy 7/17/2013
@Jarvis:有何不同?
0赞 MLK.DEV 11/7/2014
@noisy 除非显式发送到跟踪服务,否则服务器端跟踪无法看到哈希值。
2赞 AksLolCoding 7/24/2021
这只能部分回答这个问题。我们希望 url 发生变化,而不是哈希。
11赞 Nate 12/14/2009 #4

您可以添加锚标记。我在我的网站上使用它,以便我可以通过 Google Analytics 跟踪人们在页面上访问的内容。

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

var trackCode = "/#" + urlencode($("myDiv").text());
window.location.href = "http://www.piano-chords.net" + trackCode;
pageTracker._trackPageview(trackCode);
2420赞 David Murdoch 7/28/2010 #5

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

评论

12赞 Nate Anderson 3/18/2021
请注意,OP 明确表示他们不会试图导航到不同的原点;“不像我违反了跨域策略”——但是,我正在尝试这样做,并且 window.history API 不允许通过 进行跨域导航(这是合理的......正如Mozilla网站所说,“新URL必须与当前URL具有相同的来源;否则,pushState() 将抛出异常。pushState
1赞 Edison Pebojot 5/19/2021
我可以问 response.html 的值是什么吗?那是HTML字符串吗?
3赞 DeeStarks 6/5/2021
应该将哪些数据传递给“响应”?
0赞 Abhi Beckert 2/7/2022
@EdisonPebojot当您更改 URL 时,您还需要更改页面的 html 内容。从哪里获得 HTML 完全取决于开发人员,您不必像本例中那样这样做。您还需要支持后退/前进按钮并重新创建页面内容。
0赞 sshanzel 6/21/2022
是否有任何解决方法可以使用不同的域更改它?仅当目标 URL 位于同一域下时,这才有效。
837赞 Vivart 8/17/2010 #6

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

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

这里阅读更多关于这方面的信息

评论

3赞 iYazee6 7/12/2021
很好的答案,也可以使用 replaceState() 更改当前历史记录而不是添加另一个历史记录;developer.mozilla.org/en-US/docs/Web/API/History_API/......
2赞 golimar 2/1/2022
我明白了.是因为它是本地磁盘 URL 吗?A history state object with URL 'file:///C:/Users/.../newUrl' cannot be created in a document with origin 'null' and URL 'file:///C:/Users/.../oldUrl.pdf'
0赞 Rodrigo 5/9/2022
如果我用作 的第一个参数会发生什么?nullpushState()
26赞 Jeremy Warne 4/19/2011 #7

如果您要做的是允许用户为页面添加书签/共享,并且您不需要它是完全正确的 URL,并且您没有将哈希锚用于其他任何事情,那么您可以分两部分执行此操作;您使用位置。hash,然后在主页上进行检查,以查找其中包含哈希锚的 URL,并将您重定向到后续结果。

例如:

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

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

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

219赞 George Filippakos 11/19/2012 #8

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

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

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

28赞 Thomas Stjernegaard Jeppesen 11/21/2012 #9

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

9赞 Erenor Paz 9/5/2013 #10

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

自这个答案以来已经过去了将近一年,History.js 不断发展壮大,变得更加稳定和跨浏览器。现在,它可用于管理符合 HTML5 的浏览器以及许多仅使用 HTML4 的浏览器中的历史状态。在此演示中您可以看到它如何工作的示例(以及能够尝试其功能和限制。

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

最后,有关使用哈希(和哈希bang)可能存在的问题的全面解释,请查看本杰明·卢普顿(Benjamin Lupton)的此链接

27赞 Shine 1/24/2014 #11

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

parent.location.hash = "hello";

和:

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

This method will reload your page, but HTML5 introduced the that should not reload your page.history.pushState(page, caption, replace_url)

评论

2赞 OSWorX 5/12/2018
The problem with is, that if you want to redirect to another domain, the cross domain policy come in effect. While with redirecting to another domain is possible.history.pushState(..)window.location.replace(..)
190赞 Haimei 6/11/2015 #12

Here is my solution (newUrl is your new URL which you want to replace with the current one):

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

评论

9赞 Craig Jacobs 8/29/2016
Best to test first with if (history.pushState) {} Just in case old browser.
1赞 kkatusic 11/9/2017
This doesn't work any more you will get in Firefox: The operation is insecure.
0赞 codepleb 6/3/2020
And the user can even set a bookmark with that approach, beautiful! I can now update the url on user input and he can directly bookmark whatever his settings are.
1赞 Gregory Bowers 10/6/2020
hey kkatusic, thats why Craig Jacobs said TEST. You Test it by trying to execute the new html5 version (test 1) and if that fails you test the older version and if that fails you have problems, if the test succeeds for either object then you know if the brower is new or old. pretty simple logic buddy! Upvote for Craig! :)
0赞 scipilot 5/28/2021
@GregoryBowers I don't think kkatusic is saying the method doesn't exist, he said it shows a security error/warning when run. So that test would not fail and would still run the function. The test suggested by Craig does not "try to execute the new html5" function, it just checks it exists in the history object.
8赞 Prathamesh Rasam 8/15/2015 #13

Use from the HTML 5 History API.history.pushState()

Refer to the HTML5 History API for more details.

19赞 Suraj 10/27/2015 #14

Below is the function to change the URL without reloading the page. It is only supported for 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赞 Snook 5/27/2016
@Green, page is a short title for the state to which you're moving. Firefox currently ignores this parameter, although it may use it in the future. Passing the empty string here should be safe against future changes to the method. From: developer.mozilla.org/en-US/docs/Web/API/…
82赞 Alireza 7/2/2017 #15

In modern browsers and HTML5, there is a method called on window . That will change the URL and push it to the history without loading the page.pushStatehistory

You can use it like this, it will take 3 parameters, 1) state object 2) title and a URL):

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

This will change the URL, but not reload the page. Also, it doesn't check if the page exists, so if you do some JavaScript code that is reacting to the URL, you can work with them like this.

Also, there is which does exactly the same thing, except it will modify the current history instead of creating a new one!history.replaceState()

Also you can create a function to check if exist, then carry on with the rest like this: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');

Also, you can change the for , which won't reload the page. That's the way Angular uses to do SPA according to hashtag...#<HTML5 browsers

Changing is quite easy, doing like:#

window.location.hash = "example";

And you can detect it like this:

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

评论

0赞 J0ANMM 7/17/2018
Would and do the same in this case?window.onhashchangewindow.onpopstate
0赞 MD. Atiqur Rahman 9/14/2018
How to load page contents as well? It just replaces the URL
1赞 Johann 9/16/2018
Load content as you would normally do with ajax.
0赞 payne 12/8/2022
Why do you need to prepend with ? My code works without it. window.if (history.replaceState) history.replaceState({}, document.title, "?newUrl")
22赞 Dheeraj Thedijje 11/29/2019 #16

You can use this beautiful and simple function to do so anywhere on your application.

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

You can not only edit the URL but you can update the title along with it.

评论

1赞 BIOHAZARD 2/7/2020
Works like a charm even for anchors window.history.pushState('data', 'Title', '#new_location');
1赞 xeruf 2/9/2021
why don't you use the 'title' argument as title in pushState?
-1赞 Omar bakhsh 6/10/2020 #17

This is all you will need to navigate without reload

// add setting without reload 
location.hash = "setting";

// if url change with hash do somthing
window.addEventListener('hashchange', () => {
    console.log('url hash changed!');
});

// if url change do somthing (dont detect changes with hash)
//window.addEventListener('locationchange', function(){
//    console.log('url changed!');
//})


// remove #setting without reload 

history.back();

评论

0赞 Sebastian Simon 3/27/2022
“I would like to access the portion before the # hash if possible.”
8赞 Vinay Kaithwas 7/18/2020 #18

Your new url.

let newUrlIS =  window.location.origin + '/user/profile/management';

In a sense, calling pushState() is similar to setting window.location = "#foo", in that both will also create and activate another history entry associated with the current document. But pushState() has a few advantages:

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

You can check out the root: https://developer.mozilla.org/en-US/docs/Web/API/History_API

评论

1赞 xeruf 2/9/2021
please add a reference to the supposed "advantages" of pushState :)
1赞 Syed Imran Ertaza 1/10/2021 #19

This code works for me. I used it into my application in ajax.

history.pushState({ foo: 'bar' }, '', '/bank');

Once a page load into an ID using ajax, It does change the browser url automatically without reloading the page.

This is ajax function bellow.

function showData(){
    $.ajax({
      type: "POST",
      url: "Bank.php", 
      data: {}, 
      success: function(html){          
        $("#viewpage").html(html).show();
        $("#viewpage").css("margin-left","0px");
      }
    });
  }

Example: From any page or controller like "Dashboard", When I click on the bank, it loads bank list using the ajax code without reloading the page. At this time, browser URL will not be changed.

history.pushState({ foo: 'bar' }, '', '/bank');

But when I use this code into the ajax, it change the browser url without reloading the page. This is the full ajax code here in the bellow.

function showData(){
        $.ajax({
          type: "POST",
          url: "Bank.php", 
          data: {}, 
          success: function(html){          
            $("#viewpage").html(html).show();
            $("#viewpage").css("margin-left","0px");
            history.pushState({ foo: 'bar' }, '', '/bank');
          }
        });
      }
-16赞 James Bond 8/6/2021 #20

Simply use, it will not reload the page, but just the URL :

$('#form_name').attr('action', '/shop/index.htm').submit();

评论

13赞 Stefan Reich 8/27/2021
This makes no sense
3赞 Sebastian Simon 3/27/2022
This requires jQuery even if jQuery has never been mentioned in the question. This calls on a which, by default, reloads the page, which was specifically requested to be avoided. “it will not reload the page, but just the URL” is guaranteed to be false. Why was this posted as an answer to this question?submit<form>
3赞 Shehan Sachintha 4/20/2023 #21

These two lines are all you need.

    var new_url="Your modified URL";
    window.history.pushState(null,"",new_url);

评论

0赞 cssyphus 4/22/2023
How is this answer different from Alireza's answer in 2017? All you did was create a variable for the - otherwise, it is the exact same answer without the additional explanation. Also, you did not explain the purpose of the "data" or "Title" parameters, or how they can be used. Please delete this unnecessary answer. -1new_url
0赞 Shehan Sachintha 4/24/2023
Sorry for that. I edited my answer because I copy and pasted from my old project. I didn't explain it correctly and I forgot to change the details. Maybe this answer is not different. But, It worked for me. Thank anyway. :)