Проблемы с кэшем страницы в iOS 5 Safari при переходе назад/выгрузке события не запускается

tl; dr - Safari на iOS 5 так сильно кэшируется, что он разбивает мой сайт.

Я борюсь с тем, как браузер Safari в iOS 5 занимается обратным кэшем вперед, который они называют "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>

Ответы

Ответ 1

Я также искал ответ на тот же вопрос. Возвращение в iOS 5 не выполняет javascript и просто оставляет страницу в предыдущем состоянии, когда вы ушли или были перенаправлены.

Попытка найти странный "onunload" взлом, найденный в "Есть ли кросс-браузерное событие onload при нажатии кнопки "Назад" ? "Работает только для iOS 4, а не iOS 5, который не вызывает событие, как ожидалось. Николай указал на новые функции в веб-кит, называемые" pagehow "и" pagehide", которые намного надежнее, чем пример Джузеппе.

  • Вам нужно взломать эту статью: "Есть ли кросс-браузерное событие onload при нажатии кнопки "Назад" ?" для этого в iOS 4.
  • Используйте этот script, который использует новое событие, чтобы безопасно проверить, была ли загружена страница из кеша и принудительно перезагрузилась (исключая проверки 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>
    

Ответ 2

Я встречаюсь с той же проблемой.
На iOS4, когда вы перейдете на страницу homepage.html на 2.html, затем вернитесь на домашнюю страницу .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, он может исправить проблему backforward на предыдущем MobileSafari. Я просто изменил <body> на <body onUnload=""> на homepage.html, а затем с главной страницы на 2.html, при возвращении на главную страницу будет вызываться javascript на главной странице. Он работает на FF, Desktop Safari, Mobile Safari (iOS4)

Итак, как мы можем работать на iOS5? К сожалению, я не нашел решения. Но мой webapp работает на родном клиенте, я исправил это, добавив вызов reload() из native:

        if (isOS5_)
        {
            [webView stringByEvaluatingJavaScriptFromString:@"location.reload();"];
        }

когда webViewDidFinishLoad:

Ответ 3

на моем мобильном сайте, я исправил проблему с этим небольшим кодом 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();
        }
    };
}

Сценарий:

Нажав на ссылку "Страница2" с "Страница1" : После нажатия "Стр .1" закрывается, Загружается "Страница 2" и запускается загрузка и многие другие события.

[Page1] → нажмите ссылку → [Page2] → onload → onpopstate → ...

В этот момент, если вы нажмете кнопку "Назад" вашего браузера, "Страница2" получит закрыт и "Страница1" загружен и запускает загрузку и многие другие события.

[Page2] → нажмите кнопку "Назад" → [Страница1] → onload → onpopstate → ...

Нажатие кнопки "Назад" в IOS5 делает закрытие "Страница1" и "Страница2" , но страница не загружена, масштаб видового экрана поврежден и единственное событие уволен на противоположном.

[Page2] → нажмите кнопку "Назад" → [Page1] → onpopstate.

Исправление:

Исправление работает с событиями onload, onpopstate и localStorage.

onload - это первое событие, управляемое script, и в нем оно хранит текущее местоположение .href на localStorage.

Если нет ошибки, в onpopstate текущее location.href и href сохраненные должны быть одинаковыми, а script ничего не должен делать.

Использование Safari на IOS5 страница не загружается и событие onload не запускается, затем location.href и хранимые href различаются в событии onpopstate.

В этом случае просто скройте текущую страницу (для другой ошибки в видовом экране, связанной с это) и перезагрузите страницу с помощью объекта местоположения.

Ответ 4

После того, как вы узнали, как избежать одной из проблем, мы все, похоже, имеем на этом, я жестко хотел бы поделиться:)

После прочтения нескольких связанных тем о предмете, в основном о переполнении стека "самые горячие предметы", обработка "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/), проверяя событие "выгрузить" (developer.apple.com/library/IOS/ipad/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)/ "pagehow" does nohing приходится иметь дело с кратким "появлением страницы" в его предыдущем состоянии (а не в предыдущем состоянии INITIAL, но только с той страницей, в которой он был оставлен), когда пользователь переключается обратно к приложению/или разблокировать его устройство/или вернуться в приложение после его выхода.

Кажется (по крайней мере, для меня), что этот "видимый сбой страницы" был решен, когда я сделал обновление для IOS6, вроде 5 минут назад, D

Тогда я смог использовать мой веб-браузер в мобильном сафари как обычно, и после добавления его на главный экран поведение в случае "переключения приложений" или "перезапуска" с очищенным кешем или без него является таким же, как его первый запуск: вы видите страницу BLANK, а затем ваш контент (который может быть страницей, соответствующей URL-адресу, сохраненному на главном экране, или любому другому содержимому, загруженному с использованием localStorage, например [my case (..)]).

Для событий, которые я смог уловить, ни на устройствах IOS4 IOS5 мне не удалось избавиться от этого "сбоя визуальной стойкости". Я предполагаю, что из-за того, как работает "Кэш страниц", но теперь я запускаю IOS6 на iPad, так как глюка больше нет, я думаю, что команда Safari, должно быть, улучшила способ обработки "домашних экранов" webapps (.. )