【问题标题】:Change the URL in the browser without loading the new page using JavaScript更改浏览器中的 URL 而不使用 JavaScript 加载新页面
【发布时间】:2010-09-13 06:45:44
【问题描述】:

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

如果后退按钮可以重新加载原始 URL,那就太好了。

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

【问题讨论】:

  • 这太好了。当然,它仅限于同域修改。但是,由于页面重新加载是许多应用程序的一种“最后手段”,因此对路径(而不仅仅是哈希)进行一些客户端控制是合乎逻辑的步骤。
  • pushState的“某种”很好的使用:for(i=1;i<50;i++){var txt="..................................................";txt=txt.slice(0,i)+"HTML5"+txt.slice(i,txt.length);history.pushState({}, "html5", txt);}
  • 这个效果的例子:dujour.com
  • 此效果示例:facebook.com(在灯箱中打开图像时)
  • 这是个好问题。然而,这是一个可悲的情况,如果今天以这种方式提出这个问题,它会被否决并被“这不是那种让人们为你编写所有代码的网站”。

标签: javascript url html5-history fragment-identifier hashchange


【解决方案1】:

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

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

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

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

【讨论】:

  • 搜索引擎不会忽略这些内部链接(哈希)吗?在我的场景中,我希望蜘蛛也能接收这些链接。
  • @Drew,据我所知,搜索引擎无法将页面的一部分视为单独的结果。
  • 现在有一个建议让搜索引擎看到哈希:googlewebmastercentral.blogspot.com/2009/10/…
  • 可以使用hashchange 事件而不是使用setInterval 来检查document.location.hash,因为它被更多采用。 Check here for what browsers support each standard。我目前的方法是在支持它的浏览器上使用 push/popState。在其他我设置散列并且只在支持的浏览器中观看hashchange。这使得 IE
  • @gabeDel 是的,虽然我不认为 Google Analytics(分析)记录了哈希,所以它会有相同的 URL。更好的方法是使用新页面的“真实”URL 手动调用 _trackPageview
【解决方案2】:

对于 HTML 5,使用 history.pushState function。举个例子:

<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

【讨论】:

  • 你说得对,上次我用 Chrome 做实验。我刚刚在我的 Ubuntu 上尝试使用 Firefox 3.6,它没有用。我想我们将不得不等到 FF 完全支持 HTML5
  • 示例代码是从developer.mozilla.org/en/DOM/Manipulating_the_browser_history 剪切和粘贴的。在这种情况下,这实际上很难解释 foo 和 bar 的含义。
  • foo 和 bar 没有任何意义,它是一个任意定义的状态对象,可以稍后取回。
  • @Paul:是的,上面的文章提供了这些信息。
  • 发布此评论后,它适用于 firefox chrome 和 safari。不过,ipad 或 iphone 上的移动 safari 运气不好 :(
【解决方案3】:

window.location.href 包含当前 URL。你可以读取它,你可以追加它,你可以替换它,这可能会导致页面重新加载。

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

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

【讨论】:

  • 在 URL 中记录 javascript 状态正是我想要做的
【解决方案4】:

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

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

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

【讨论】:

  • 如果非重新加载更改仅限于路径、查询字符串和片段,则问题不大——即不是权威(域等)。
  • youtube.com/user/SilkyDKwan#p/u/2/gTfqaGYVfMg 是一个例子,可以尝试切换视频:)
  • 您只能更改 location.hash(# 之后的所有内容),正如 Matthew Chumley 在接受的答案中指出的那样。
  • 你使用 Facebook 吗? Facebook 使用history.pushState() 更改网址而不重新加载。
  • Paul Dixon,你应该注意到 facebook 收件箱,当你点击左侧的名字时,只是 URL 发生了变化,新的聊天被加载到聊天框中,页面没有刷新。 WebGL 上还有更多的网站,他们也这样做
【解决方案5】:

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

JavaScript pushState 和 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. 状态对象 — 状态对象是一个 JavaScript 对象,它与 pushState() 创建的新历史条目相关联。每当用户导航到新状态时,都会触发一个 popstate 事件,并且该事件的 state 属性包含历史条目的 state 对象的副本。

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

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

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

【讨论】:

    【解决方案6】:

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

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

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

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

    【讨论】:

    • 抱歉,您的回答不正确。是的,您可以更改网址。
    • 是的,您可以使用 html5 历史 API,但它不是跨浏览器,但您可以使用将回退到哈希 url 的 poly-fill。
    【解决方案7】:

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

    【讨论】:

      【解决方案8】:

      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 后面的井号 (#!)。

      【讨论】:

        【解决方案9】:

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

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

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

        【讨论】:

          【解决方案10】:

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

          我想这就是你需要的。

          【讨论】:

            【解决方案11】:

            对我有用的是 - history.replaceState() 函数如下 -

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

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

            【讨论】:

              【解决方案12】:

              我想知道只要页面中的父路径相同,它是否可行,只是附加了一些新的东西。

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

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

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

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

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

              【讨论】:

                【解决方案13】:

                我的代码是:

                //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;
                    });
                });
                

                就是这样:)

                【讨论】:

                  【解决方案14】:

                  我已经成功了:

                  location.hash="myValue";
                  

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

                  var articleId = window.location.hash.replace("#","");
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2013-04-25
                    • 1970-01-01
                    • 2020-06-20
                    • 2013-10-12
                    • 1970-01-01
                    • 2011-10-27
                    • 2012-08-23
                    • 2016-04-12
                    相关资源
                    最近更新 更多