302

我怎么会有一个JavaScript操作,它可能对当前页面有一些影响,但也会改变浏览器中的 URL,所以如果用户点击重新加载或书签,那么使用新的 URL?

如果后退按钮可以重新加载原始 URL,那也很好。

我正在尝试在 URL 中记录 JavaScript 状态。

4

14 回答 14

187

如果您希望它在尚不支持的浏览器中工作history.pushStatehistory.popState“旧”方法是设置片段标识符,这不会导致页面重新加载。

基本思想是将window.location.hash属性设置为包含您需要的任何状态信息的值,然后使用window.onhashchange 事件,或者对于不支持的旧浏览器onhashchange(IE < 8,Firefox < 3.6),定期检查查看哈希是否已更改(setInterval例如使用)并更新页面。您还需要检查页面加载时的哈希值以设置初始内容。

如果您使用的是 jQuery,则有一个hashchange 插件,它将使用浏览器支持的任何方法。我确信其他库也有插件。

需要注意的一件事是与页面上的 id 发生冲突,因为浏览器将滚动到任何具有匹配 id 的元素。

于 2008-09-25T22:08:40.663 回答
122

在 HTML 5 中,使用history.pushState函数. 举个例子:

<script type="text/javascript">
var stateObj = { foo: "bar" };
function change_my_url()
{
   history.pushState(stateObj, "page 2", "bar.html");
}
var link = document.getElementById('click');
link.addEventListener('click', change_my_url, false);
</script>

和一个href:

<a href="#" id='click'>Click to change url to bar.html</a>

如果要更改 URL 而不向后退按钮列表添加条目,请history.replaceState改用。

于 2010-11-19T06:20:18.737 回答
37

window.location.href 包含当前 URL。您可以从中读取,可以附加到它,也可以替换它,这可能会导致页面重新加载。

如果听起来像,您想在 URL 中记录 javascript 状态以便可以将其添加为书签,而无需重新加载页面,请将其附加到当前 URL 后 # 并让一段由 onload 事件触发的 javascript 解析当前URL 以查看它是否包含已保存状态。

如果您使用 ? 而不是#,您将强制重新加载页面,但是由于您将在加载时解析保存的状态,这实际上可能不是问题;这将使前进和后退按钮也能正常工作。

于 2008-09-25T22:19:36.673 回答
21

我强烈怀疑这是不可能的,因为如果是这样,那将是一个令人难以置信的安全问题。例如,我可以制作一个看起来像银行登录页面的页面,并让地址栏中的 URL 看起来像真正的银行

也许如果您解释为什么要这样做,人们可能会提出替代方法...

[2011 年编辑:自从我在 2008 年写下这个答案以来,关于HTML5 技术的更多信息已经曝光,只要它来自同一来源,就可以修改 URL]

于 2008-09-25T22:07:09.247 回答
9

jQuery有一个很棒的插件来改变浏览器的 URL,叫做jQuery-pusher

JavaScriptpushState和 jQuery 可以一起使用,例如:

history.pushState(null, null, $(this).attr('href'));

例子:

$('a').click(function (event) {

  // Prevent default click action
  event.preventDefault();     

  // Detect if pushState is available
  if(history.pushState) {
    history.pushState(null, null, $(this).attr('href'));
  }
  return false;
});

仅使用JavaScript history.pushState()来更改引荐来源网址,该引荐来源网址在您更改状态后创建的 XMLHttpRequest 对象的 HTTP 标头中使用。

例子:

window.history.pushState("object", "Your New Title", "/new-url");

pushState() 方法:

pushState()接受三个参数:一个状态对象、一个标题(当前被忽略)和(可选)一个 URL。让我们更详细地检查这三个参数中的每一个:

  1. state 对象— state 对象是一个 JavaScript 对象,它与由pushState(). 每当用户导航到新状态时,都会触发一个 popstate 事件,并且该事件的 state 属性包含历史条目状态对象的副本。

    状态对象可以是任何可以序列化的对象。因为 Firefox 将状态对象保存到用户的磁盘,以便在用户重新启动浏览器后可以恢复它们,所以我们对状态对象的序列化表示施加了 640k 个字符的大小限制。如果将序列化表示大于此的状态对象传递给pushState(),则该方法将引发异常。如果您需要更多空间,我们鼓励您使用 sessionStorage 和/或 localStorage。

  2. title — Firefox 当前忽略此参数,尽管它可能在未来使用它。在此处传递空字符串应该可以安全地防止将来对该方法进行更改。或者,您可以为您要迁移到的州传递一个简短的标题。

  3. URL — 新历史条目的 URL 由该参数给出。请注意,在调用 之后,浏览器不会尝试加载此 URL pushState(),但它可能会在稍后尝试加载 URL,例如在用户重新启动浏览器之后。新的 URL 不需要是绝对的;如果是相对的,则相对于当前 URL 进行解析。新 URL 必须与当前 URL 同源;否则,pushState()将抛出异常。该参数是可选的;如果未指定,则将其设置为文档的当前 URL。

于 2013-10-08T21:04:06.183 回答
8

浏览器安全设置防止人们直接修改显示的 url。您可以想象会导致的网络钓鱼漏洞。

在不更改页面的情况下更改 url 的唯一可靠方法是使用内部链接或哈希。例如:http://site.com/page.html变为http://site.com/page.html#item1。这种技术常用于 hijax(AJAX + 保存历史)。

这样做时,我通常只使用以哈希作为 href 的操作的链接,然后使用 jquery 添加单击事件,该事件使用请求的哈希来确定和委托操作。

我希望这能让你走上正确的道路。

于 2008-09-25T22:11:14.370 回答
4

有一个 Yahoo YUI 组件(浏览器历史管理器)可以处理这个:http: //developer.yahoo.com/yui/history/

于 2008-09-25T23:47:45.043 回答
3

Facebook 的照片库在 URL 中使用 #hash 来执行此操作。以下是一些示例 URL:

在点击“下一步”之前:

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507

点击“下一步”后:

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507#!/photo.php?fbid=496435457507&set=a.218088072507.133423.681812507&pid=5887085&id=681812507

请注意紧跟新 URL 的井号 (#!)。

于 2011-01-11T15:43:21.650 回答
3

我提出一个更简单的答案,

window.history.pushState(null, null, "/abc")

这将/abc在浏览器 URL 中的域名之后添加。只需复制此代码并将其粘贴到浏览器控制台中,即可看到 URL 更改为“ https://stackoverflow.com/abc

于 2019-02-15T18:19:13.683 回答
2

有一个 jquery 插件 http://www.asual.com/jquery/address/

我认为这就是你所需要的。

于 2011-04-20T14:03:27.483 回答
2

对我有用的是-history.replaceState()功能如下-

history.replaceState(data,"Title of page"[,'url-of-the-page']);

这不会重新加载页面,您可以通过 javascript 事件来使用它

于 2018-04-26T06:52:24.900 回答
1

我想知道只要页面中的父路径相同,它是否可行,只有新的东西被附加到它上面。

所以就像假设用户在页面上:http://domain.com/site/page.html 然后浏览器可以让我做location.append = new.html ,页面变成:http://domain.com/site/page.htmlnew.html并且浏览器不会改变它。

或者只是允许该人更改 get 参数,所以让我们location.get = me=1&page=1.

所以原始页面变为http://domain.com/site/page.html?me=1&page=1并且它不会刷新。

# 的问题是当哈希改变时数据没有被缓存(至少我不这么认为)。因此,就像每次加载新页面时一样,而非Ajax页面中的后退和前进按钮能够缓存数据,而无需花费时间重新加载数据。

据我所见,Yahoo 历史记录已经一次性加载了所有数据。它似乎没有执行任何 Ajax 请求。因此,当 adiv用于处理不同的方法超时时,不会为每个历史状态存储该数据。

于 2009-03-31T20:33:38.690 回答
1

我的代码是:

//change address bar
function setLocation(curLoc){
    try {
        history.pushState(null, null, curLoc);
        return false;
    } catch(e) {}
        location.hash = '#' + curLoc;
}

和行动:

setLocation('http://example.com/your-url-here');

和例子

$(document).ready(function(){
    $('nav li a').on('click', function(){
        if($(this).hasClass('active')) {

        } else {
            setLocation($(this).attr('href'));
        }
            return false;
    });
});

就这样 :)

于 2013-10-29T18:07:14.100 回答
0

我在以下方面取得了成功:

location.hash="myValue";

它只是添加#myValue到当前 URL。如果您需要在页面加载上触发事件,您可以使用它location.hash来检查相关值。请记住从例如#返回的值中删除location.hash

var articleId = window.location.hash.replace("#","");
于 2014-06-23T11:56:41.333 回答