13

Thanks for reading.

I've noticed that if I have a page that has one or more ajax requests open, and I click a link to leave a page, or refresh it, it will wait for the ajax requests to complete before unloading.

This isn't usually an issue, but if the request takes a while, it can be.

I'm looking for something like:

$(window).bind("beforeunload", function() {AjaxRequest.abort();});

to automatically abort requests before unload, but not quite sure how to find the ajax requests. Would they be under window somewhere?

Eli
  • 97,462
  • 20
  • 76
  • 81

5 Answers5

10

The $.ajax() jQuery method returns the XMLHttpRequest Object. This means you can apply standard methods on the object, like abort().

To unload use the built in unload jQuery event method.

var myajax = $.ajax(...); 
$(window).unload( function () { myajax.abort(); } );
Luca Matteis
  • 29,161
  • 19
  • 114
  • 169
  • i'm getting a js error "myajax.abort" is not a function (jquery 1.3.2) has anyone tamed the "abort beast?" – taber Sep 14 '09 at 03:12
  • edit: i think it's because i was using ".responseText" at the end of my $.ajax(...) call. i took out .responseText and there is no error now. yay. – taber Sep 14 '09 at 03:19
  • `unload` method has been removed in Jquery :/ – Badiparmagi Dec 19 '17 at 12:00
8

The following code is tested and aborts all outstanding jQuery ajax requests on page unload in Chrome, but it gets used by Edge and IE using clients as well without error.

Put the following as the first jQuery ready handler:

$(onPageLoaded)

And put this somewhere accessible:

function onPageLoaded() {
    var jqxhrs = [];

    $(window).bind("beforeunload", function (event) {
        $.each(jqxhrs, function (idx, jqxhr) {
            if (jqxhr)
                jqxhr.abort();
        });
    });

    function registerJqxhr(event, jqxhr, settings) {
        jqxhrs.push(jqxhr);
    }

    function unregisterJqxhr(event, jqxhr, settings) {
        var idx = $.inArray(jqxhr, jqxhrs);
        jqxhrs.splice(idx, 1);
    }

    $(document).ajaxSend(registerJqxhr);
    $(document).ajaxComplete(unregisterJqxhr);
};
  • This works great. Your ajax `error` function will still get invoked for the abort, so make sure to test for `textStatus!='abort'` if you're logging console errors, etc... – dhc Apr 14 '16 at 16:16
  • I've added the latest version of this. The original code had a while() loop and only exited when there were no xhr objects left. However, this would find null xhr entries in the list, and would error in some cases. – yourpublicdisplayname Apr 16 '16 at 05:59
  • Sorry for asking. By this: Put the following as the first jQuery ready handler, did you mean to use it like this => $(onPageLoaded).ready(...) ? – Another Weeb Jan 25 '23 at 02:40
4

I just had this issue, I was doing a long-loop in PHP which was being called from $.ajax. My solution was to add session_write_close(); before the long loop.

My theory is, Chrome requests the next page before cancelling any background ajax requests. If your ajax request is the same _SESSION as the page you're navigating away from AND TO, then you have a deadlock before even your first line of PHP code is hit.

servermanfail
  • 2,532
  • 20
  • 21
2

You have to persist all you ajax request and when page is being reloading abort all requests. Sample

var _requests = [];

var _abortAllRequests = function () {
    $(_requests).each(function (i, xhr) { xhr.abort(); });

    _requests = [];
}

$(window).on("beforeunload", function () { 
    _abortAllRequests();
});

somewhere in your code

 _requests.push($.ajax(...))

Additionally you can pop done requests using $.ajaxSetup with events ajaxStart ajaxStop, but its up to you

Madman
  • 3,171
  • 2
  • 32
  • 44
1

Think you need window.onunload event plus AjaxRequestX = $.get(...) for each request, maybe keep objects in array and go through them on unload.

Sergey Galashyn
  • 6,946
  • 2
  • 19
  • 39