在使用pushState(在Chrome中)后,浏览器的返回按钮无法正常工作

29

我正在JS响应中使用这种类型的行

if (history && history.pushState){
     history.pushState(null, null, '<%=j home_path %>');
}

但是,当我在浏览器中点击“后退”时,我看到的是响应的JS代码而不是之前的页面。

有没有办法让返回按钮正常工作,以便它会重新请求上一个URL的页面(在home_path被推送的之前)?

更新:

我找到了这个..似乎其他人也有同样的问题..历史记录.js也无法解决它

所以为了确认一些评论..这只发生在chrome中

我的想法

我认为所有这些问题的根源是popstate请求与pushstate文档(js响应)相同类型。需要做的是在popstate请求html响应..我只是不知道怎么做

更多更新:

http://railscasts.com/episodes/246-ajax-history-state中提到要使用

 $(window).bind("popstate", function() {
      $.getScript(location.href);
    });
这解决了问题,但根据了解jQuery $.getScript(),如果没有ajax缓存,它会添加时间戳,这会污染URL,关闭它会使其再次无法正常工作。 有人知道如何解决这个问题吗?
更新更多:
我在整个互联网上追踪了问题的足迹,并以Chrome中的一个问题结束,该问题指向Rails问题(Firefox可以正常工作),以及rails-ujs中的问题涉及在响应中未包括Vary标头。
示例可在此处找到。

1
你能提供完整的源代码和输出吗?你提供的代码块是正确的。我需要更多信息来帮助解决你的问题。 - Aadit M Shah
1
'<%=j home_path %>' 的结果是哪个字符串? - Simon
它的结果是 /home - Nick Ginanto
4个回答

12

我目前正在尝试做一些事情。

 response.headers['Vary'] = 'Accept'

乍一看似乎解决了问题。

如果有人遇到同样的问题,请检查并让我知道。


2
谢谢,这个头文件也解决了我的问题。 这是一个不寻常的问题,在我没有遇到此问题的情况下,但我的瑞典客户遇到了。 在Apache中,可以以这种方式设置这个头文件。希望这对那些有同样问题的人有所帮助。在.htaccess中写入以下代码: <IfModule mod_headers.c> Header append Vary: Accept </IfModule> - Dipesh KC
1
谢谢!但是response.headers['Vary'] = 'X-Requested-With'更合适。 - tomasbedrich

9
你需要向popstate事件添加一个监听器。
window.onpopstate = function(event) {
    //load the page
};

当按下返回按钮时,URL会被更改,然后触发popstate事件。您需要在popstate监听器中加载与更改的URL匹配的详细信息。 一个很好的popstate示例 一些浏览器在页面首次加载时会触发popstate事件,导致无限页面加载循环。可以通过添加以下检查来避免此问题。
var loadPage = window.history.state;
window.onpopstate = function(event) {
    if (loadPage) 
        //load the page
};

当调用pushState时,请将loadPage设置为true。

history.pushState(null, null, '<%=j home_path %>');
loadPage = true;

这种技术适用于所有支持html5历史记录api的浏览器。

这不起作用。因为加载页面的脚本导致无限循环,每次加载页面都会再次调用popstate。 - Nick Ginanto
@NickGinanto 我已经编辑了我的答案,以避免你的无限循环问题。 - graham mendick

3
发生了一个问题,涉及到 sinatra 和 chrome。
解决方法如下:
$.ajaxSetup({ cache: false });

奇怪的是,尽管在控制台中我可以看到ajax xhr请求时间戳的url,但它并没有显示在浏览器的url栏中。 您可以尝试从保存在pushstate上的url名称中剥离时间戳。 - trompa
谢谢!我尝试了很多解决方案,但这个是唯一适用于我的。给你100分。 - user287689
这并不是我需要的确切解决方案,但它指引了我正确的方向 - 我在一个ajax请求中指定了 cache: true。将其移除后问题得到解决。谢谢你 - 给你100分(和一个赞)! - Brad Werth

0
我已经在我的浏览器上使用本地HTML文件测试了这段代码,但是出现了控制台安全错误:
SecurityError: The operation is insecure.
  history.pushState(null, null, '<%=j home_path %>');

我可以理解操作浏览器历史记录可能被视为潜在的危险行为,所以我想你应该检查一下是否也发生了这种情况。尝试使用Firebug JavaScript控制台。同时,本地和http:// HTML文件之间的行为可能会有所不同。

话虽如此,根据我的观察,history数组的最后一个元素基本上是当前页面,因此如果您想更改前一个页面,可以通过使用两个pushState()命令来实现 - 首先将您需要的前一个元素推入,然后再次推入当前路径。如果我正确理解了您的问题。


请注意,<%=j home_path %> 是 erb 语法,预处理后将等于有效路径。也许我应该使用完整路径。 - Nick Ginanto
我不知道,我在本地尝试过,只有使用 file:// 路径才能正常工作。所有在本地域之外的都无法工作。我认为首先要检查是否有任何安全错误,可以使用 try...catch 指令。 - Okarin
你在使用哪个版本的FF,@Okarin?对我来说,在FF19中提供的代码完全正常。 - Simon
FF17,我现在在Mageia Linux上发现了这个问题。我想我也会尝试新版本的。 - Okarin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接