在Safari 5中防止后退按钮缓存

23

最近Safari 5发布了,结果导致我的网站出现了一些问题。我的网站是运行经典ASP的动态网站(虽然这应该不重要),该网站对历史记录栈有一些创意用法。例如,您可以在列出产品的页面上,然后转到有关某个产品的详细信息,然后更改产品(管理视图)。当您在产品上单击保存时,信息会通过AJAX发送到服务器,并发出history.back()。这在所有浏览器中都很好用(包括Safari <= 4),但是在新发布的Safari 5中它停止工作了。似乎在Safari 5中,当您单击返回时,它实际上并没有刷新页面,而只是从缓存中加载页面,这意味着详细视图中所做的更改不会显示出来。如何使这在Safari 5中也能正常工作?这是我目前用于关闭缓存的代码(包含在每个页面的顶部):

Dim pStr
pStr = "private, no-cache, no-store, must-revalidate"
Response.AddHeader "pragma","no-cache"      '?
Response.AddHeader "cache-control", pStr    '?  Er ikke sikker på om disse 3 siste er nødvendige.
Response.AddHeader "cache-control", "post-check=0, pre-check=0"     '?  Er ikke sikker på om disse 3 siste er nødvendige.
Response.AddHeader "Expires", "Mon, 26 Jul 1997 05:00:00 GMT"       '?
Response.AddHeader "Last-Modified", Now()
3个回答

46

空的 unload 处理程序将不再起作用。 相反,您可以检查 onpageshow 事件的 persisted 属性。 它在初始页面加载时设置为 false。 当页面从 bfcache 加载时,它设置为 true。

当页面从 bfcache 加载时,强制重新加载是一个巧妙的解决方案。

window.onpageshow = function(event) {
    if (event.persisted) {
        window.location.reload() 
    }
};

如果您正在使用jQuery,请执行以下操作:
$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        window.location.reload() 
    }
});

1
非常好的修复 - 经过确认在iOS 6(iPhone和iPad)上有效!谢谢Mika! - Jesse
2
这在 Safari 6 的桌面版也适用。旧的 window.onunload 的 hack 不再一致有效,现在应该被视为“正确”的答案。 - Sam Sehnert
1
这在iPad上可以工作。不幸的是(至少对我来说),它会在从睡眠模式中唤醒时重新加载页面。如果用户已经更改了一堆表单元素,导致各种显示更改,那么用户必须重新开始。是否有一种方法只在从后退按钮而不是在唤醒时重新加载页面? - Chris Valdivia
你可以将表单的状态保存到本地存储中。有现成的插件可供使用:https://github.com/shaneriley/jquery_remember_state - Mika Tuupola
1
你的 jQuery 版本有一个小 bug。在最后一个分号之前缺少一个 )。 - GeekyMonkey
显示剩余5条评论

7

经过一番搜索和挖掘,我找到了一个解决方案,尽管我对它并不太满意。在body标签中设置onunload=""会导致Safari使页面无效并在执行window.history.back();时重新加载。


1
我一直遇到类似的问题,但我希望在浏览器后退时重新验证用户(学生轮流使用iPad)。在笔记本电脑上,onunload = "" hack 似乎可以强制Safari重新验证,但在iPad上的移动Safari上却不行。有什么想法吗? - John

3
这里有另一种方法:
    function invalidateBackCache() {
        // necessary for Safari: mobile & desktop
    }

    window.addEventListener("unload", invalidateBackCache, false);

我选择这种方法是因为在.Net中将HTML (onunload="") 添加到body标签需要修改三个文件。使用jQuery设置onunload属性也无法解决这个问题。
这种方法对于移动Safari(iPad)也有效。

2
不行,这对我也没用(iPad上的返回按钮)。只有在刷新时才有效。 - sirmak
1
这个想法是正确的/对我有用。我使用了以下依赖于jQuery的代码:$(window).on('unload', function () { }); - Sam
请注意,最近版本的移动Safari报告了卸载事件存在问题,因此您可能需要仔细检查。 - Georgii Ivankin

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