Как предотвратить перезагрузку веб-страницы из кеша при использовании мобильного браузера Safari?

Mobile Safari использует специальный механизм кэширования Page Cache (здесь), который в основном сохраняет текущую страницу живым, но зимует, когда мы переходим к другому стр. Таким образом, он может сразу отображать предыдущую страницу в своем последнем состоянии, когда пользователь нажимает кнопку back.

Это полезно для навигации и просмотра веб-страниц, но для особых случаев это становится раздражающим, поскольку вам может потребоваться получить новую копию страницы при каждом переходе пользователя на эту страницу. (в моем случае у меня есть страницы: логин и главная страница).

Я полностью понимаю, что ничто не мешает пользователю открывать несколько вкладок одного и того же приложения. Я не беспокоился об этом.

Решение кросс-браузер для предотвращения кэширования страницы не помогает, так как Safari сохраняет страницу открытой, но невидимой и приостановленной.

window.onpageshow и обработка event.persisted не помогают, поскольку кажется, что браузер не запускает событие onpageshow по некоторым причинам во второй раз (когда вы нажимаете кнопку back).

Примечание для тех, кто не знает, что такое событие onpageshow: Apple не рекомендует использовать события load и unload, потому что с концепцией кеш страниц эти события не имеют четкого смысла. Таким образом, onpageshow должен делать то, что мы ожидаем от события load.

Ответ 1

Когда пользователь нажимает кнопку "Назад", вы получите тот же документ, что и раньше (старая страница, которая была приостановлена). Поэтому, если вы обрабатываете событие onpagehide и делаете некоторые изменения на странице перед переходом на новую страницу, ваши изменения сохраняются там.

Я попытался добавить блок script к body непосредственно перед навигацией:

if (isSafari) {
        window.addEventListener('pagehide', function(e) {
            var $body = $(document.body);
            $body.children().remove();
                $body.append("<script type='text/javascript'>window.location.reload();<\/script>");
        });
    }

это не работает, потому что script немедленно выполняется, когда я собирался выполнить его, когда пользователь вернется на страницу.

НО, если вы отложите свои изменения DOM после выхода pagehide обратного вызова (что-то вроде этого):

if (isSafari) {
        window.addEventListener('pagehide', function(e) {
            var $body = $(document.body);
            $body.children().remove();

            // wait for this callback to finish executing and then...
            setTimeout(function() {
                $body.append("<script type='text/javascript'>window.location.reload();<\/script>");
            });
        });
    }

TADA работает! как только пользователь нажимает кнопку "Назад" на следующей странице, Safari загружает приостановленную страницу и выполняет этот новый блок script, который ранее не выполнялся.

Ответ 2

Еще одно потенциальное решение - посмотреть флаг event.persisted, чтобы определить, кэшируется он или нет:

window.onpageshow = function(event) {
    if (event.persisted) {
        window.location.reload() 
    }
};