Проблемы с Page Cache в iOS 5 Safari при переходе назад / выгрузить событие не срабатывает
tl; dr - Safari на iOS 5 так сильно кеширует, что ломает мой сайт.
Я борюсь с тем, как браузер Safari в iOS 5 работает с обратным кэшем, который они называют "Page Cache". То, как это описано здесь, объясняет поведение очень хорошо.
Проще говоря, Page Cache делает это так, что когда вы покидаете страницу, мы "приостанавливаем" ее, а когда вы возвращаетесь, мы нажимаем "play".
Это вызывает проблемы на моем сайте. При использовании кнопки "Назад" большинство других браузеров будут показывать вам страницу в том состоянии, в котором она была загружена. Не Safari на iOS 5, он показывает страницу, как вы в последний раз ее покинули. Простым примером будет отключение кнопки отправки. Если я использую Javascript, чтобы отключить кнопку отправки, то отправлю форму, когда вы нажмете назад, кнопка отправки все равно будет отключена. Это было проблемой в других браузерах, включая настольную версию Safari, но она решается путем установки в обработчике события onload пустой функции. Я полагаю, что это говорит браузеру о недействительности кэша, потому что в этой функции могло произойти что-то важное. Кажется, этот взлом не работает для Safari на iOS 5.
Ниже проблема сводится к самым необходимым. Когда вы загрузите test.html, вы увидите текст "Оригинальный текст". Если щелкнуть ссылку, этот текст изменится на "Изменен текст - пересылка на следующую страницу", а через 3 секунды вы будете перенаправлены на test2.html. Все хорошо до этого момента во всех браузерах. Во всех других браузерах, когда вы нажимаете кнопку "Назад", вы видите текст "Исходный текст", но в Safari для iOS 5 вы увидите "Измененный текст - пересылка на следующую страницу".
Любые предложения о том, как с этим бороться?
Это простой пример
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>
4 ответа
Я также искал ответ на ту же проблему. Возвращение в iOS 5 не выполняет никакого javascript и просто оставляет страницу в прежнем состоянии, которое было, когда вы уходили или были перенаправлены.
Попытка странного взлома onunload, найденного в " Есть ли событие кросс-браузерной загрузки при нажатии кнопки" Назад "?", Работала только для iOS 4, но не для iOS 5, которая не вызывает событие, как ожидается. Николай указал на новые функции в веб-наборе, называемые "pagehow" и "pagehide", которые намного более надежны, чем пример Джузеппе.
- Вам нужен взлом из этой статьи: " Есть ли событие загрузки через браузер при нажатии кнопки" Назад "?", Чтобы это работало в iOS 4.
Используйте этот сценарий, который использует новое событие, чтобы безопасно проверить, была ли страница загружена из кэша, и принудительно выполнить перезагрузку (избегая проверок URL-адресов и локального хранилища, а также включает iPod) для 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>
Я встречаюсь с той же проблемой.
На iOS4, когда вы переходите homepage.html к 2.html, а затем возвращаетесь к homepage.html, js вызываться не будет. когда вы переходите с homepage.html на 2.html, с 2.html вы продолжаете переходить к 3.html, а затем с 3 на 2 возвращаетесь на домашнюю страницу, вызывается JS! Да, это ужасно!
Но на iOS5 MobileSafari, он всегда не может быть вызван:(Возможно, это ошибка кеша на iOS5. Я тестировал на iOS 5.0.0 и 5.0.1, получил тот же результат.
Но когда вы реализуете событие onUnload на body
элемент, это может исправить проблему обратной на предыдущем MobileSafari. Я просто поменяла <body>
в <body onUnload="">
в homepage.html, затем с домашней страницы до 2.html, при возвращении на домашнюю страницу будет вызываться javascript на домашней странице. Работает на FF, Desktop Safari, Mobile Safari (iOS4)
Итак, как мы можем сделать на iOS5? К сожалению, я не нашел решения. Но мое веб-приложение работает в нативном клиенте, я исправил это, добавив reload()
звонок из родного:
если (isOS5_) { [webView stringByEvaluatingJavaScriptFromString:@"location.reload();"]; }
когда webViewDidFinishLoad:
На моем мобильном сайте я исправил проблему с этим небольшим кодом JS:
if ((/iphone|ipad.*os 5/i).test(navigator.appVersion)) {
window.onload=function () {
localStorage.setItem("href",location.href);
};
window.onpopstate=function () {
var a=localStorage.getItem("href"),
b=location.href;
if (b!==a&&b.indexOf((a+"#"))===-1) {
document.body.style.display="none";
location.reload();
}
};
}
Сценарий:
Нажатие на ссылку "Page2" в "Page1": после нажатия "Page1" закрывается, "Page2" загружается и запускает загрузку и многие другие события.
[Page1] -> нажмите на ссылку -> [Page2] -> onload -> onpopstate -> ...
В этот момент, если вы нажмете кнопку "Назад" вашего браузера, "Страница2" закроется, а "Страница1" загрузится и запустит загрузку и многие другие события.
[Page2] -> нажмите на кнопку "Назад" -> [Page1] -> onload -> onpopstate -> ...
Нажатие кнопки "Назад" в IOS5 приводит к закрытию "Страница1" и появляется "Страница2", но страница не загружается, масштаб области просмотра повреждается, и вызывается только одно событие - onpopstate.
[Page2] -> нажмите на кнопку "Назад" -> [Page1] -> onpopstate.
Исправление:
Исправление работает с событиями onload, onpopstate и объектом localStorage.
onload - это первое событие, управляемое сценарием, в котором оно сохраняет текущий файл location.href в localStorage.
Если нет никаких ошибок, в onpopstate текущее location.href и сохраненный href должны быть одинаковыми, и скрипт ничего не должен делать.
При использовании Safari на IOS5 страница не загружается и событие onload не вызывается, тогда location.href и сохраненный href отличаются в событии onpopstate.
В этом случае просто скройте текущую страницу (для другой ошибки в области просмотра, связанной с этим) и перезагрузите страницу с объектом местоположения.
После того, как мы выяснили, как избежать одной из проблем, с которыми мы все сталкиваемся, я хочу поделиться:)
После прочтения нескольких связанных тем на эту тему, в основном о переполнении стека "горячими темами", обработайте "Page Cache" ( http://www.webkit.org/blog/427/webkit-page-cache-i-the-basics/ и http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/), проверка события "unload" ( developer.apple.com/library/IOS/ipad) /#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html) / "pageshow" не имеет ничего общего с кратким "появлением страницы" в своем предыдущем состоянии (не в состоянии INITIAL предыдущей страницы, а только в виде страницы как таковой) был оставлен), пока пользователь переключается обратно в приложение / или разблокирует свое устройство / или возвращается в приложение после выхода из него.
Кажется (по крайней мере для меня), что этот "видимый сбой страницы" был решен, когда я сделал обновление для IOS6, как 5 минут назад;D
После этого я смог использовать свое веб-приложение в мобильном сафари в обычном режиме, и после добавления его на домашний экран поведение в случае "переключения приложения" или "перезапуска" с очищенным кешем или без него такое же, как и при первом запуске.: вы видите пустую страницу, а затем ваш контент (который может быть страницей, соответствующей URL-адресу, который был сохранен на главном экране, или любым другим контентом, загруженным с использованием localStorage, например [my case (..) ]).
Для событий, которые я смог поймать, ни на устройствах IOS4 IOS5 мне не удалось избавиться от этого "визуального сбоя в постоянстве". Я думаю, это из-за того, как работает "Page Cache", но теперь я использую IOS6 на iPad, так как проблем больше нет, я думаю, команда Safari, должно быть, улучшила способ обработки веб-приложений "домашнего экрана" (..)