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

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

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

26 голосов
/ 20 марта 2012

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

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

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

на моем мобильном сайте я исправил проблему с этим небольшим 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»: после нажатия «Страница 1 »закрывается,« Страница 2 »загружается и запускает загрузку и многие другие события.

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

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

[Page2] ->нажмите кнопку «Назад» -> [Page1] -> onload -> onpopstate -> ...

При нажатии кнопки «Назад» в IOS5 происходит закрытие «Page1», и появляется «Страница2», но страница не загружена,масштаб области просмотра искажается, и вызывается только событие onpopstate.

[Page2] -> нажмите кнопку «Назад» -> [Page1] -> onpopstate.

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

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

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

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

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

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

1 голос
/ 11 декабря 2011

У меня такая же проблема.
На 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() из собственного:

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

когда webViewDidFinishLoad:

0 голосов
/ 20 сентября 2012

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

После прочтения нескольких связанных тем по теме, в основном по переполнению стека «горячими темами», обработкой «кэша страниц» (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" не имеет ничего общего с кратким "появлением страницы" в своем предыдущем состоянии (не предыдущая страница в начальном состоянии, но только на той странице, на которой она была оставлена), пока пользователь переключается обратно в приложение / или разблокирует свое устройство / или возвращается в приложение после выхода из него.

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

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

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

...