48

我为当地社区大学做一些小的编程和网络工作。工作包括维护一个非常庞大且破坏灵魂的网站,该网站由 VBScript、javascript、Dreamweaver 生成的杂乱无章的大杂烩和各种骗子多年来说服他们购买的附加组件的集合组成。

几天前,我接到一个电话“该网站正在为使用 Safari 的人锁定!” 好的,第一步下载Safari(v3.1.2),第二步上网。一切似乎都运行良好。

长话短说,我终于找到了这个问题,它与 Safari 的后退按钮有关。该网站使用了一个花哨的 javascript 菜单,该菜单适用于我尝试过的所有浏览器,包括 Safari,这是第一次。但是在 Safari 中,如果您点击页面外的链接然后点击后退按钮,则菜单不再起作用。

我做了一个精简的网页来说明原理。

<!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>

加载页面,您会看到警告框。然后点击页面外的链接并点击后退按钮。在 IE 和 Firefox 中,您会再次看到警告框,而在 Safari 中则不会。

经过激烈的谷歌搜索,我发现其他人也有类似的问题,但没有真正令人满意的答案。所以我的问题是,在用户点击后退按钮后,如何让我的页面在 Safari 中以与其他浏览器中相同的方式工作?

如果这是一个愚蠢的问题,请保持温和,javascript 对我来说有点新。

4

12 回答 12

19

Stefan 的 iframe 解决方案有效,但如果这还不够优雅,我发现以下 JavaScript 也可以解决它:

window.onunload = function(){};

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

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

于 2008-12-06T21:49:39.640 回答
10

把它放在body标签里 <body onunload="">

每次点击返回按钮时,这将强制 safari、chrome、FF 重新加载

于 2011-05-01T04:33:16.853 回答
9

请不要遵循任何告诉您忽略缓存的建议。页面被缓存是有原因的——改善用户体验。你使用的方法会让用户体验更差,所以除非你讨厌你的用户,否则不要那样做。

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

pageshow事件将在您期望该onload事件触发的同时触发,但当通过缓存提供页面时它也将起作用。无论如何,这似乎是您想要的。

于 2013-11-12T22:18:14.873 回答
8

这是 Mobile Safari 的一个很好的解决方案:

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

来源

我根据自己的需要对其进行了修改,但没关系。(如果你不修改它,刷新时会出现恼人的白屏)。

于 2012-09-06T06:55:46.907 回答
7

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>

更多细节

于 2008-08-23T07:36:39.470 回答
4
$(window).bind("pageshow", function(event) {
  if (event.originalEvent.persisted) {
    window.location.reload() 
  }
});

mshah最近在这里回答了。

于 2016-04-21T14:58:06.737 回答
3

我不知道是什么导致了问题,但我知道谁能帮助你。Safari 建立在Webkit之上,缺少 Apple(他们不那么具有社区意识),Webkit 团队可能知道问题所在。

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

于 2008-08-23T06:50:34.947 回答
3

我注意到一些非常相似的东西。我认为这是因为 Firefox 和 IE 在返回时再次从服务器检索页面,而 Safari 则没有。您是否尝试过添加页面过期/无缓存标头?当我发现这种行为但还没有时间时,我打算调查它。

于 2008-08-23T07:05:40.510 回答
1

我知道这个线程已经有一年了,但我刚刚使用 ProjectSeven 的 Safari 后退按钮修复了一个相同的 Safari 专用问题。奇迹般有效。

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

于 2010-05-27T21:23:49.953 回答
0

在 iPad 上遇到了同样的问题。

不是那么漂亮,但它有效:)。这个怎么运作。

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

加载页面时,计数器和时间同步。在后退按钮上,计数器从它停止的地方继续,并且时间戳和计数器之间存在间隙。如果间隙大于 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();
    }
}
于 2013-06-10T12:12:00.103 回答
0

在我的 Angular 应用程序中,我使用此条件来解决问题。首先,我在下面添加了onunload=""事件句柄index.html

<body class="mat-typography" onunload="">
    <app-root></app-root>
</body>

然后在我的组件ngOnInit方法中,我添加了如下代码

  public ngOnInit(): void {
    window.onpageshow = (event) => {
        if (event.persisted) {
            document.body.style.display = "none";
            location.reload();
        }
    };
    ...
  }
于 2021-08-27T06:45:26.987 回答
0

试试这个
if(performance.navigation.type == 2) {
alert("Hello");
}

于 2020-01-09T13:02:12.480 回答