【发布时间】:2011-12-20 19:09:00
【问题描述】:
tl;dr - iOS 5 上的 Safari 缓存非常困难,它正在破坏我的网站。
我正在为 iOS 5 中的 Safari 浏览器处理后向缓存(他们称之为“页面缓存”)的方式而苦苦挣扎。 here 的描述方式很好地解释了这种行为。
很简单,页面缓存可以做到这一点,当您离开页面时,我们会“暂停”它,而当您返回时,我们会按“播放”。
这导致我的网站出现问题。使用后退按钮时,大多数其他浏览器会以加载状态显示页面。不是 iOS 5 上的 Safari,它会显示您上次离开时的页面。一个简单的例子是禁用提交按钮。如果我使用 Javascript 禁用提交按钮,然后提交表单,当您单击返回时,提交按钮仍将被禁用。这在其他浏览器(包括桌面版 Safari)中一直存在问题,但通过将 onload 事件处理程序设置为空白函数来解决此问题。我相信这会告诉浏览器使缓存无效,因为该函数中可能发生了一些重要的事情。这个 hack 似乎不适用于 iOS 5 上的 Safari。
以下问题归结为基本要素。当您加载 test.html 时,您将看到文本“原始文本”。当您单击链接时,该文本将更改为“更改的文本 - 转发到下一页”,然后在 3 秒内您将被转发到 test2.html。到目前为止,在所有浏览器中一切都很好。在所有其他浏览器中,当您单击返回按钮时,您将看到的文本是“原始文本”,但在 iOS 5 的 Safari 上,您会看到“更改的文本 - 转发到下一页”。
关于如何处理这个问题有什么建议吗?
这是一个简单的例子
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
<form method="post" action="formtest2.asp">
Test: <input type="text" name="test"/>
<input type="submit" value="Submit"/>
</form>
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>
【问题讨论】:
-
关于这个的更多信息。似乎我测试过的所有浏览器(Firefox、IE、Safari 桌面)都按此顺序触发 pagehide 和卸载。 iOS 5 上的 Safari 只会触发 pagehide。
-
打开新标签页时,不会触发 unload 事件,只是页面隐藏。打开新选项卡时,您希望能够导航回旧选项卡并查看离开时一样的页面。问题是,当我们在同一个选项卡/窗口中从一个页面导航到下一个页面时,应该按 w3c 触发 unload 事件,但不是。 w3.org/TR/DOM-Level-2-Events/events.html。 “当 DOM 实现从窗口或框架中删除文档时,会发生 unload 事件。此事件对 BODY 和 FRAMESET 元素有效。”
-
任何使用 location.reload() 的解决方案都会失败,因为对于此功能,iOS 5 上的 Safari 只会执行 GET,而不像所有其他浏览器一样执行 POST。
-
我们找到了适合我们的解决方法。我们在 HTTPS 中运行我们的整个应用程序,从而避免了后向缓存。
-
没什么可补充的,只是这是一个完美的例子,说明了一个 SO 问题应该是什么样子的,恕我直言...... +1!
标签: javascript ios5 mobile-safari web browser-cache