4

We have the following AJAX throttler. This was implemented to be able to perform many (20+) ajax requests for one page without the remainder timing out just because the first X requests took a total of 60 seconds.

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);
    }
}

However, because these requests are sitting in a Javascript queue, when the user attempts to load a new page, the developer tools show the responses in the NET area of the new page. Our app has a check in place for privacy reasons to not allow this kind of behavior. Is this normal for browsers, or is it some sort of bug, or am I doing something wrong?

theB3RV
  • 894
  • 4
  • 13
  • 33

1 Answers1

4

A clean solution would be to listen to the window.onbeforeunload event to abort any ajax requests that have yet to receive a response.

The beforeunload event should be used rather than unload for the following reasons:

1) The beforeunload event is more reliable than unload event:

The exact handling of the unload event has varied from version to version of browsers. For example, some versions of Firefox trigger the event when a link is followed, but not when the window is closed. In practical usage, behavior should be tested on all supported browsers, and contrasted with the proprietary beforeunload event.

source:

2) The beforeunload event can be cancelled whereas the unload event cannot be cancelled. This would give you the flexibility if you wanted to prompt the user when beforeunload event takes place. The confirmation will ask the user if they would like to continue to navigate to the other page or if they would like to cancel because not all ajax requests have completed.

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

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

sources:

Community
  • 1
  • 1
peterdotjs
  • 1,526
  • 1
  • 13
  • 19
  • 2
    Why do you choose onbeforeunload instead of onunload? – theB3RV Mar 03 '15 at 13:26
  • I should note that I have another function bound to the before unload event and have noticed that it fires when other events occur (file download and flash player launch, for example) In which cases I would not want my ajax requests to quit. – theB3RV Mar 03 '15 at 20:12
  • 1
    To prevent file download from from triggering beforeunload event I've found this solution : http://stackoverflow.com/questions/14391531/distinguish-onbeforeunload-for-file-download-vs-page-change/26919572#26919572 – peterdotjs Mar 03 '15 at 22:11
  • I could not find anything mentioning flash player causing the event to fire. One possibility is to look at the evt object that is passed to the beforeunload callback to see if anything specifies it is from the flash player and to do something accordingly. – peterdotjs Mar 03 '15 at 22:25
  • The javascript to launch the flash player is provided by a third party, and it seems they monitor the onbeforeunload action. – theB3RV Mar 04 '15 at 13:26
  • Also, we are using javascript to handle the file download `window.location = current.ExportToFileUrl;` – theB3RV Mar 04 '15 at 15:09
  • To address the file download you can use the iframe technique: http://stackoverflow.com/questions/2452110/download-binary-without-triggering-onbeforeunload#answer-5714978 – peterdotjs Mar 04 '15 at 16:42
  • 1
    Regarding the flash player, simply monitoring the beforeunload won't cause any issue. You had mentioned previously that it was triggering the beforeunload event. As the flash player is very specific and I feel like it is getting off topic of the origin question, can you create another question for this? – peterdotjs Mar 04 '15 at 16:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/72270/discussion-between-theb3rv-and-peterdotjs). – theB3RV Mar 04 '15 at 20:28