导航返回/未触发事件时 iOS 5 Safari 中的页面缓存问题

tl;dr - iOS 5 上的 Safari 缓存非常困难,它正在破坏我的网站.

tl;dr - Safari on iOS 5 is caching so hard, it is breaking my site.

我正在为 iOS 5 中的 Safari 浏览器处理后向缓存(他们称之为页面缓存")的方式而苦苦挣扎.这里的描述方式解释了行为非常好.

I am struggling with the way the Safari browser in iOS 5 deals with back forward cache, which they call "Page Cache". The way it is described here explains the behavior very well.

很简单,页面缓存可以做到这一点,当您离开页面时,我们会暂停"它,而当您返回时,我们会按播放".

Quite simply, the Page Cache makes it so when you leave a page we "pause" it and when you come back we press "play."

这导致我的网站出现问题.使用后退按钮时,大多数其他浏览器会以加载状态显示页面.不是 iOS 5 上的 Safari,它会显示您上次离开时​​的页面.一个简单的例子是禁用提交按钮.如果我使用 Javascript 禁用提交按钮,然后提交表单,当您单击返回时,提交按钮仍将被禁用.这在其他浏览器(包括桌面版 Safari)中一直存在问题,但通过将 onload 事件处理程序设置为空白函数来解决此问题.我相信这会告诉浏览器使缓存无效,因为该函数中可能发生了一些重要的事情.这个 hack 似乎不适用于 iOS 5 上的 Safari.

This is causing problems throughout my site. When using the back button, most other browsers will show you the page in the state it was loaded. Not Safari on iOS 5, it shows you the page as you last left it. A simple example would be the disabling of a submit button. If I use Javascript to disable a submit button, then submit a form, when you click back the submit button will still be disabled. This has been an issue in other browsers, including the desktop version of Safari, but it is solved by setting the onload event handler to a blank function. I believe this tells the browser to invalidate the cache because something important could have happened in that function. This hack does not seem to work for Safari on iOS 5.

以下问题归结为基本要素.当您加载 test.html 时,您将看到文本原始文本".当您单击链接时,该文本将更改为更改的文本 - 转发到下一页",然后在 3 秒内您将被转发到 test2.html.到目前为止,在所有浏览器中一切都很好.在所有其他浏览器中,当您单击后退按钮时,您将看到的文本是原始文本",但在 iOS 5 的 Safari 上,您会看到更改的文本 - 转发到下一页".

Below is the issue boiled down to the bare essentials. When you load test.html you will see the text "Original Text". When you click the link, that text will change to "Changed text - forwarding to next page", then in 3 seconds you will be forwarded to test2.html. All is good up to this point in all browsers. In all other browsers, when you click the back button, the text you will see is "Original Text", but on Safari for iOS 5 you will see "Changed text - forwarding to next page".

关于如何处理这个问题有什么建议吗?

Any suggestions on how to deal with this?

这是一个简单的例子

test.html

<script>
function changeText() {
    el = document.getElementById("text");
    el.innerHTML = "Changed text - forwarding to next page";
    setTimeout("forward()",3000);       
}
function forward() {
    document.location.href = "test2.html";
}
</script>
<div id="text">Original Text</div>
<a href="Javascript:changeText()">Click Here</a>
<script>
window.onunload = function(){};
</script>

test2.html

<div>Click back button</div>

这是使用表单帖子的第二个示例.这是我的应用程序如何工作的一个简单示例.当您导航回 formtest2.asp 时,您应该会看到发布的表单值并且 div 文本应该是原始的.

formtest.asp

formtest.asp

<form method="post" action="formtest2.asp">
    Test: <input type="text" name="test"/>
    <input type="submit" value="Submit"/>
</form>

formtest2.asp

formtest2.asp

<script>
function changeText() {
    el = document.getElementById("text");
    el.innerHTML = "Changed text - forwarding to next page";
    setTimeout("forward()",3000);       
}
function forward() {
    document.location.href = "test2.html";
}
</script>

<%
Dim test
test = Request("test")
Response.Write("Test value: " & test & "<br />")
%>

<div id="text">Original Text</div>
<a href="Javascript:changeText()">Click Here</a>
<script>
window.onunload = function(){};
</script>

test2.html

<div>Click back button</div>

推荐答案

我也在寻找同样问题的答案.在 iOS 5 中返回不会执行任何 javascript,只是将页面留在您离开或被重定向时的先前状态.

I was also looking for an answer to the same issue. Going back in iOS 5 does not execute any javascript and just leaves the page in the previous state it was when you left or were redirected.

尝试在Is单击后退按钮时是否存在跨浏览器 onload 事件?"仅适用于 iOS 4,不适用于未按预期调用事件的 iOS 5.Nickolay 指出了 web-kit 上的新功能,称为pageshow"和pagehide",它们比 Giuseppe 的示例可靠得多.

Trying the weird "onunload" hack found in "Is there a cross-browser onload event when clicking the back button?" only worked for iOS 4, not iOS 5 which does not call the event as expected. Nickolay pointed out new functions on web-kit called "pageshow" and "pagehide" which are much more reliable than Giuseppe's example.

  1. 您需要这篇文章中的技巧:那里单击后退按钮时的跨浏览器 onload 事件?"以便在 iOS 4 中正常工作.
  2. 使用这个脚本,它使用新事件安全地检查页面是否从缓存中加载并强制重新加载(避免 URL 检查和本地存储,还包括 iPod):

  1. You need the hack from this article: "Is there a cross-browser onload event when clicking the back button?" for this to work in iOS 4.
  2. Use this script which uses the new event to safely check if the page was loaded from cache and force a reload (avoiding URLs checks and local storage and also include iPods) for iOS 5:

<body onunload="">
...
<script type="text/javascript">
if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) {
  window.onpageshow = function(evt) {
    // If persisted then it is in the page cache, force a reload of the page.
    if (evt.persisted) {
      document.body.style.display = "none";
      location.reload();
    }
  };
}
</script>

相关文章