Браузеры продолжают выполнять Javascript после PageUnload и новой PageLoad

У нас есть следующий дроссель AJAX. Это было реализовано, чтобы иметь возможность выполнять множество (20+) запросов ajax для одной страницы без тайм-аута оставшейся части только потому, что первые X-запросы заняли в общей сложности 60 секунд.

RequestThrottler: {
    maximumConcurrentRequests: 3, //default to 3        
    requestQueue: new Array(),
    numberOfRequestCurrentlyProcessing: 0,

    addRequestToQueue: function (currentRequest) {
        var self = this;
        self.requestQueue.push(currentRequest);

        if (self.numberOfRequestCurrentlyProcessing < self.maximumConcurrentRequests) { self.sendNextRequest(); }
    },

    sendNextRequest: function () {
        var self = this;
        if (self.numberOfRequestCurrentlyProcessing >= self.maximumConcurrentRequests) { return; }
        if (self.requestQueue.length === 0) { return; }

        var currentRequest = self.requestQueue.pop();
        self.numberOfRequestCurrentlyProcessing++;
        AJAX.SendAjaxRequest(currentRequest.url, currentRequest.httpMethod, 
            function(data){
                self.numberOfRequestCurrentlyProcessing--;
                currentRequest.onSuccessCallback(data);
                self.sendNextRequest();
            }, 
            function(){
                self.numberOfRequestCurrentlyProcessing--;
                currentRequest.onErrorCallback();
                self.sendNextRequest();
            });
    },

    sendUpdateRequest: function (currentRequest) {
        var self = this;
        self.addRequestToQueue(currentRequest);
    }
}

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


person theB3RV    schedule 24.02.2015    source источник


Ответы (1)


Чистым решением было бы прослушивать событие window.onbeforeunload для abort любых запросов ajax, которые еще не получили ответа.

Событие beforeunload следует использовать вместо unload по следующим причинам:

1) Событие beforeunload надежнее, чем событие unload:

Точная обработка события выгрузки варьировалась от версии к версии браузеров. Например, некоторые версии Firefox запускают событие при переходе по ссылке, но не при закрытии окна. На практике поведение следует тестировать во всех поддерживаемых браузерах и сравнивать с проприетарным событием beforeunload.

источник:

2) Событие beforeunload можно отменить, а событие unload нельзя отменить. Это даст вам гибкость, если вы хотите указать пользователю, когда происходит событие beforeunload. Подтверждение спросит пользователя, хотят ли они продолжить переход на другую страницу или они хотят отменить, потому что не все запросы ajax были выполнены.

window.addEventListener("beforeunload", function (e) {
  var confirmationMessage = "\o/";

  (e || window.event).returnValue = confirmationMessage;     // Gecko and Trident
  return confirmationMessage;                                // Gecko and WebKit
});

источники:

person peterdotjs    schedule 03.03.2015
comment
Почему вы выбираете onbeforeunload вместо onunload? - person theB3RV; 03.03.2015
comment
Я должен отметить, что у меня есть еще одна функция, привязанная к событию перед выгрузкой, и я заметил, что она срабатывает, когда происходят другие события (например, загрузка файла и запуск флеш-плеера). В таких случаях я бы не хотел, чтобы мои запросы ajax завершались. - person theB3RV; 03.03.2015
comment
Чтобы загрузка файла не запускалась до события загрузки, я нашел следующее решение: stackoverflow.com/questions/14391531/ - person peterdotjs; 04.03.2015
comment
Я не мог найти ничего, что упоминало бы о флеш-плеере, вызывающем срабатывание события. Одна из возможностей состоит в том, чтобы посмотреть на объект evt, который передается в функцию обратного вызова beforeunload, чтобы увидеть, указывает ли что-нибудь, что он исходит от флэш-плеера, и предпринять соответствующие действия. - person peterdotjs; 04.03.2015
comment
JavaScript для запуска флеш-плеера предоставляется третьей стороной, и, похоже, они отслеживают действие onbeforeunload. - person theB3RV; 04.03.2015
comment
Кроме того, мы используем javascript для обработки загрузки файла window.location = current.ExportToFileUrl; - person theB3RV; 04.03.2015
comment
Чтобы решить проблему загрузки файла, вы можете использовать технику iframe: stackoverflow.com/questions/2452110/ - person peterdotjs; 04.03.2015
comment
Что касается флеш-плеера, простой мониторинг перед выгрузкой не вызовет никаких проблем. Вы упомянули ранее, что он запускал событие beforeunload. Поскольку флеш-плеер очень специфичен, и я чувствую, что он уходит от темы вопроса о происхождении, вы можете создать для него еще один вопрос? - person peterdotjs; 04.03.2015
comment
Давайте продолжим это обсуждение в чате. - person theB3RV; 04.03.2015