Проблема с кнопкой «Назад» при публикации формы AJAX на многостраничном сайте - PullRequest
0 голосов
/ 01 октября 2019

В моем проекте Django у меня есть страница с таблицей устройств и формой для добавления нового устройства. А теперь я хочу перевести этот пост в AJAX. Я сделал это с помощью jQuery Form Plugin (http://malsup.github.com/jquery.form.js):

$('#deviceAddForm').ajaxForm({
                dataType:  'json',
                async: true,
                cache: false,
                success:   function (data) {
                    device_row = '<tr>' + 
                            '<td>' + data['name'] + '</td>' +
                            '<td>' + data['description'] + '</td>' +
                        '</tr>';
                    $(device_row).hide().appendTo($('#deviceTableBody')).show("slow")
                }
});

И теперь у меня проблема с браузером "кнопка назад". Если пользователь публикует некоторые устройства, переходит на другой сайт, а затемНазад (с помощью кнопки «Назад» в браузере) дополнительное содержимое AJAX не отображается.

Эта проблема является обычной для AJAX, и все найденные решения относятся к History API . Содержимое AJAX обновляется, должен быть history.pushState вызов, а кнопки браузера назад / вперед должны обрабатываться через событие window.onpopstate. Может быть, я что-то упускаю, но этот способ работает, только если пользователь перемещается только на одной конкретной страницеСайт приложения (SPA). Если пользователь, например, заходит в Google и обратно, onpopstate событие не сработает ( HTML5 History API: «popstate» не вызывается при переходе назад с другой страницы ). Похоже, что это не работает в каждом случае со SPA, и мой сайт даже не является SPA.

Я вижу простое решение - каждый раз перезагружать страницу даже для путешествий по истории. rsal:

function detectIE() {
    // this function is needed cause IE reloads page 
    // even if it is accessed through browser back button

    var ua = window.navigator.userAgent;
    var msie = ua.indexOf('MSIE ');
    if (msie > 0) {
        // IE 10 or older
        return true;
    }

    var trident = ua.indexOf('Trident/');
    if (trident > 0) {
        // IE 11
        var rv = ua.indexOf('rv:');
        return true;
    }
    return false;
}

if (!!window.performance && (window.performance.navigation.type == 2) && !detectIE()) {
    window.location.reload()
}

(это работает, но, возможно, проверку кнопки «Назад» следует сочетать с новым PerformanceNavigationTiming API )

Но этот метод неэффективен, если перезагрузить страницузанимает много времени. Поэтому единственное решение, которое я придумал, это:

$('#deviceAddForm').ajaxForm({
                dataType:  'json',
                async: true,
                cache: false,
                success:   function (data) {
                    device_row = '<tr>' + 
                            '<td>' + data['name'] + '</td>' +
                            '<td>' + data['description'] + '</td>' +
                        '</tr>';
                    // save rows to sessionStorage
                    device_rows = (sessionStorage.getItem("device_rows") === null) ?
                                   '' : sessionStorage.getItem("device_rows");
                    device_rows = device_rows + device_row;
                    sessionStorage.setItem("device_rows", device_rows);
                    $(device_row).hide().appendTo($('#deviceTableBody')).show("slow")
                }
});


function detectIE() {
    // this function is needed cause IE reloads page 
    // even if it is accessed through browser back button

    var ua = window.navigator.userAgent;
    var msie = ua.indexOf('MSIE ');
    if (msie > 0) {
        // IE 10 or older => return version number
        return true;
    }

    var trident = ua.indexOf('Trident/');
    if (trident > 0) {
        // IE 11 => return version number
        var rv = ua.indexOf('rv:');
        return true;
    }
    return false;
}

if (!!window.performance && (window.performance.navigation.type == 2) && !detectIE()) {
    // detect browser history travel
    device_rows = sessionStorage.getItem("device_rows");
    if (device_rows)
        $(device_rows).hide().appendTo($('#deviceTableBody')).show("slow")
} else {
    // page was refreshed
    sessionStorage.removeItem("device_rows");
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...