JavaScript - событие bfcache/pageshow - event.persisted всегда имеет значение false?

В стандартном веб-приложении Java / SpringMVC / JSP / jQuery я пытаюсь обнаружить событие "Назад" (или history.go(-1)), чтобы обновить (AJAX) итоговое содержимое компонента / панели, когда Я возвращаюсь на страницу (где мы можем изменить данные бэкэнда, отображаемые компонентом итога).

Я попробовал следующее в JavaScript (после нескольких сообщений на StackExchange о том, как этого добиться):

<script type="text/javascript">
$(document).ready(function() {
    window.onpageshow = function(event) {
        console.log("Event:");
        console.dir(event);
        if (event.persisted) {
            alert("non-jQuery - back to page - loaded from bfcache");
        } else {
            alert("non-jQuery - loaded page from server");
        }
    };
    $(window).on("pageshow", function(event){
        console.log("Event:");
        console.dir(event);
        if (event.originalEvent.persisted) {
            alert("jquery - back to page - loaded from bfcache");
        } else {
            alert("jquery - loaded page from server");
        }
    });
});
</script>

Я использую OpenSUSE Linux и пробовал это с FireFox и Chrome (последние версии), но каждый раз persisted атрибут установлен в false (Я вижу это в консоли JavaScript и по всплывающим предупреждениям из приведенного выше кода). Я имею в виду каждый раз, независимо от того, был ли он загружен с сервера или показан снова через кнопку "Назад" (или ссылку "Назад").

Я намеревался сделать AJAX-вызов для перезагрузки итогового компонента / панели с обновленными данными с сервера, если страница отображалась с помощью кнопки "Назад" или history.go(-1) вызов.

Я также попытался установить обработчик выгрузки (который ничего не делает), чтобы предотвратить помещение страницы в bfcache, но он все еще показывает версию с кэшированием bf и event.persisted (или же event.originalEvent.persisted) установлен на false,

Правильно ли управляется это свойство в Linux? Я делаю что-то глупое в моем коде? Любая помощь или идеи будут высоко ценится, спасибо!

4 ответа

Я обнаружил, что скрытые кнопки ввода не являются надежным решением, поскольку они могут содержать неправильное значение, когда пользователь переходит на страницу и затем нажимает кнопку Обновить. Некоторые браузеры (Firefox) сохраняют входные значения при обновлении, поэтому каждый раз, когда пользователь нажимает обновить, оно будет обновляться снова, поскольку кнопка ввода содержит неправильное значение. Это типичный сценарий для форумов (пользователь просматривает тему, нажимает кнопку "Назад", чтобы вернуться к списку тем, и может продолжать нажимать кнопку "Обновить", чтобы проверить наличие новых тем).

Как отметил Грегуар Клермон, event.persisted глючит в chrome (и IE), но это не исправлено ни для одного браузера на февраль 2017 года. Хорошая новость в том, что вы можете положиться на window.performance.navigation.type == 2 для хрома и IE. По иронии судьбы Firefox ненадежен для последнего, но это не должно иметь значения, поскольку он надежен для event.persisted, Следующий код работал для меня:

if (document.addEventListener) {
    window.addEventListener('pageshow', function (event) {
        if (event.persisted || window.performance && 
            window.performance.navigation.type == 2) 
        {
            location.reload();
        }
    },
   false);
}

Это похоже на ошибку в Chrome (также присутствует в IE11).

Я нашел следующий обходной путь:

<input type="hidden" id="cacheTest"></input>
<script>
  var input = document.querySelector('#cacheTest')

  if (input.value === "") {
    // the page has been loaded from the server,
    // equivalent of persisted == false
  }
  else {
    // the page has been loaded from the cache,
    // equivalent of persisted == true
  }

  // change the input value so that we can detect
  // if the page is reloaded from cache later
  input.value = "some value"
</script>

Это использует тот факт, что в большинстве браузеров, когда страница загружается из кэша, значения полей формы также сохраняются.

Я знаю, что это немного поздно, но это работает для меня:

window.onpageshow = function(e) {

    if (e.persisted) {

        alert("Page shown");
        window.location.reload();
    }
};

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

Держать ниже код в любом месте файла JS. Он ограничивает нажатие кнопки "Назад" на странице (или форме).

window.onload = function () { window.history.forward(); }

Другие вопросы по тегам