浏览器在“页面卸载”和新的“页面加载”之后仍会执行Javascript。

4
我们有以下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区域显示响应。出于隐私原因,我们的应用程序设置了一个检查以防止这种行为。这是浏览器的正常行为吗?还是某种错误或我做错了什么?
1个回答

4
一种简洁的解决方案是监听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
});

来源:

这些链接提供了关于beforeunload和unload事件的详细信息。

2
为什么你选择 onbeforeunload 而不是 onunload? - theB3RV
我应该注意到,我已经绑定了另一个函数到before unload事件,并且已经注意到它在其他事件发生时触发(例如文件下载和Flash播放器启动)。在这些情况下,我不希望我的ajax请求退出。 - theB3RV
1
为了防止文件下载触发 beforeunload 事件,我找到了这个解决方案:https://dev59.com/EWYq5IYBdhLWcg3wjBQM#26919572 - peterdotjs
启动Flash播放器的JavaScript由第三方提供,他们似乎监控onbeforeunload操作。 - theB3RV
1
关于Flash播放器,仅仅监控beforeunload事件不会引起任何问题。您之前提到它触发了beforeunload事件。由于Flash播放器非常特殊,我感觉这已经偏离了最初的问题,您能否为此创建另一个问题? - peterdotjs
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接