10

I'm trying to send a PUT request on the unload event, however the request is always cancelled.

Answers here suggests it's

  1. not possible: How to perform an ajax call on page unload?

  2. possible: How do I send an AJAX request upon page unload / leaving?

Can I send an AJAX request on unload, if so how can I without being cancelled.

Note: I don't care about the response, I don't need a response. Just need to send some info to the server saying the page was closed without keep alive checks.

hakre
  • 193,403
  • 52
  • 435
  • 836
Douglas Gaskell
  • 9,017
  • 9
  • 71
  • 128
  • It is impossible with modern browsers because it is a race condition. Answer is no different than the first link. – epascarello Mar 28 '16 at 23:47
  • Are you using jQuery? or javascript only? – Leo Mar 28 '16 at 23:48
  • I am using JQuery @epascarello I am not expecting a response, I don't need a response. If I do the same using another async communication method in something like Google Apps Script (As a web app) the request successfully executes. – Douglas Gaskell Mar 29 '16 at 00:05
  • https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#Adapting_Sync_XHR_usecases_to_the_Beacon_API – epascarello Mar 29 '16 at 00:09
  • @epascarello Thank you, that link was very informative and has me going in the right direction to avoid delaying the closing of the page. – Douglas Gaskell Mar 29 '16 at 00:15

2 Answers2

10

The question is a duplicate (I should have realized that at the time). I've posted a version of this answer here on the other question and made this a Community Wiki.


Doing standard ajax calls in a page unload handler is being actively disabled by browsers, because waiting for it to complete delays the next thing happening in the window (for instance, loading a new page). Although you can't do PUT with it, the replacement for synchronous ajax in unload handlers is sendBeacon. sendBeacon lets you send data to your server without holding up the page you're doing it in:

window.addEventListener("unload", function() {
  navigator.sendBeacon("/log", yourDataHere);
});

The browser will send the data without preventing / delaying whatever is happening in the window (closing it, moving to a new paeg, etc.).

Beacons are POSTs, not PUTs, but other than that it's exactly what you're looking for.

Note that the unload event may not be reliable, particularly on mobile devices. You might combine the above with sending a beacon on visibilitychange as well.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
8

All you need to do is make the ajax call synchronous. That way the browser will wait for the response before closing the window/tab and it will not be cancelled.

$(window).unload(function(){
    $.ajax({
        type: 'PUT',
        url: '/your_url.php',
        async:false, //IMPORTANT, the call will be synchronous
        data: {}
    }).done(function(data) {                
        console.log('complete');
    });
});
Leo
  • 834
  • 8
  • 14
  • 8
    This will stop working before too much longer, browsers are actively killing it. Although you can't do PUT with it, the replacement for synchronous ajax in unload handlers is [`sendBeacon`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon). – T.J. Crowder Aug 22 '19 at 08:43
  • 4
    @T.J.Crowder you may want to make what you are saying an answer. I got here from a google search, tried the code above and I could not get it working. sendBeacon worked like a charm, the only thing to note is that the request stays in the pending status even though it completes as the browser doesn't expect a response. – Daniel Black Mar 19 '20 at 19:42
  • @DanielBlack - Done. – T.J. Crowder Mar 20 '20 at 07:21