Safari后退button问题

我为当地社区学院做了一些小规模的编程和networking工作。 包括维护一个非常大的和灵魂破坏的网站,包括一个VBScript的大杂烩,javascript,Dreamweaver生成的cruft和各种conmen说服他们购买多年的附加组合。

几天前,我接到一个电话:“网站正在locking使用Safari的人!” 好吧,第一步下载Safari(v3.1.2),第二步网站冲浪。 一切似乎正常工作。

长话短说我终于孤立了这个问题,它涉及到Safari的后退button。 该网站使用花式裤子的JavaScript菜单,在我尝试过的所有浏览器中都能正常使用,包括Safari。 但是在Safari中,如果您closures页面的链接,然后点击后退button,菜单将不再起作用。

我做了一个削减的网页来说明原则。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>Safari Back Button Test</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body onload="alert('Hello');"> <a href="http://www.codinghorror.com">Coding Horror</a> </body> </html> 

加载页面,你会看到警告框。 然后按照页面上的链接并点击后退button。 在IE和Firefox中,你再次看到警告框,在Safari中你不知道。

经过大量的search,我发现了其他类似的问题,但没有真正令人满意的答案。 所以我的问题是,如何让我的网页在用户点击后退button后在Safari中以与在其他浏览器中一样的方式工作?

如果这是一个愚蠢的问题,请温柔,JavaScript对我来说有点新鲜。

Stefan的iframe解决scheme,但如果这不够优雅,我觉得下面的JavaScript也解决了它:

 window.onunload = function(){}; 

也就是说,如果你的菜单是JavaScript,那么你可能更喜欢用JavaScript解决这个问题。

卸载事件处理程序定义的想法来自这个Firefox 1.5的文章: https : //developer.mozilla.org/en/Using_Firefox_1.5_caching 。

把这个放在body标签<body onunload="">

这将强制Safari浏览器,铬,FF每次你点击后退button重新加载

以下是移动Safari的一个很好的解决scheme:

 /*! Reloads page on every visit */ function Reload() { try { var headElement = document.getElementsByTagName("head")[0]; if (headElement && headElement.innerHTML) headElement.innerHTML += " "; } catch (e) {} } /*! Reloads on every visit in mobile safari */ if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) { window.onpageshow = function(evt) { if (evt.persisted) { document.body.style.display = "none"; location.reload(); } }; } 

( 来源 )

我修改了我的需要,但是,这是好的。 (如果你不修改它刷新刷新白屏)。

请不要遵循任何告诉您忽略caching的build议。 页面caching的原因 – 提高用户体验。 你使用的方法会使用户的体验变得更糟,所以除非你恨你的用户,否则不要这样做。

Safari(桌面和iOS)的正确解决scheme是使用pageshow事件,而不是onload事件(请参阅https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching )。

pageshow事件将在您期望onload事件触发的同时触发,但是在通过caching提供页面时也会起作用。 这似乎是你想要的。

一个iframe解决了这个问题:

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>Safari Back Button Test</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body onload="alert('Hello');"> <a href="http://www.codinghorror.com">Coding Horror</a> <iframe style="height:0px;width:0px;visibility:hidden" src="about:blank"> this prevents back forward cache </iframe> </body> </html> 

更多细节

我不知道是什么原因造成这个问题,但是我知道谁可能会帮助你。 Safari是build立在Webkit上的 ,缺less苹果(谁不是那么关注社区) Webkit团队可能知道问题是什么。

这根本不是一个愚蠢的问题。

我注意到一些非常相似的东西。 我认为这是因为Firefox和IE在回去的时候再次从服务器上获取页面,而Safari则没有。 你尝试添加页面过期/没有caching头? 当我发现行为但还没有时间的时候,我会去查看它。

 $(window).bind("pageshow", function(event) { if (event.originalEvent.persisted) { window.location.reload() } }); 

mshah最近在这里 回复 。

我知道这个线程已经有一年了,但是我只是使用ProjectSeven的Safari后台修复function修复了一个完全相同的仅用于Safari的问题。 奇迹般有效。

http://www.projectseven.com/extensions/info/safaribbfix/index.htm

在iPad上有同样的问题。

不是那么漂亮,但它的作品:)。 怎么运行的。

我意识到,在iPad Safari上,按下后退button后,页面不会重新加载。 我在页面上每秒都放一个计数器,并保存当前的时间戳。

当页面加载时,计数器和时间是同步的。 在返回button上,计数器继续停止,并在时间戳和计数器之间存在差距。 如果间隙大于500毫秒,强制重新加载页面。

在文件action.js中

 var showLoadingBoxSetIntervalVar; var showLoadingBoxCount = 0; var showLoadingBoxLoadedTimestamp = 0 function showLoadingBox(text) { var showLoadingBoxSetIntervalVar=self.setInterval(function(){showLoadingBoxIpadRelaod()},1000); showLoadingBoxCount = 0 showLoadingBoxLoadedTimestamp = new Date().getTime(); //Here load the spinner } function showLoadingBoxIpadRelaod() { //Calculate difference between now and page loaded time minus threshold 500ms var diffTime = ( (new Date().getTime()) - showLoadingBoxLoadedTimestamp - 500)/1000; showLoadingBoxCount = showLoadingBoxCount + 1; var isiPad = navigator.userAgent.match(/iPad/i) != null; if(diffTime > showLoadingBoxCount && isiPad){ location.reload(); } }