javascriptajaxgoogle-chromebeaconwindow.onunload

JavaScript - send AJAX call on tab close (DELETE request)


I want to send an AJAX DELETE request through Javascript when the user closes the tab. The flow is the following:

When the user attempts to close the tab, a onbeforeunload event takes place, then if the user confirms to leave the page the onunload event takes place and tries to execute the deleteRequest function, which is a synchronous ajax delete request.

window.onbeforeunload = function(){
        return 'Are you sure you want to leave?';
}; 

window.onunload = function(){
    deleteRequest();
};

function deleteRequest(){
let url = new URL("http://......");
let request = new XMLHttpRequest();
request.onreadystatechange = function () {
    if(request.readyState == 4){
        if(request.status === 200){
            console.log('success');
        }
    }
}
request.open("DELETE", url, false);
try{
    request.send();
}
catch(e){
    console.log(e);
}
}

Unfortunately, it seems that Google Chrome does not support anymore this since when a tab closes it kills all the pending events, and in the console of the browser I can see the following message

DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://.....': Synchronous XHR in page dismissal. See https://www.chromestatus.com/feature/4664843055398912 for more details. at deletRequest(.......js:411:17) at window.onunload

Please note that I have already seen many topics on this issue before on SO but the solutions did not really help since most of them are out of date since the policy of chrome on this changed quite recently, like this or this.

It seems that most people propose navigator.sendBeacon to achieve this, but in the documentation I saw only ways to make a POST request using this, any thoughts? Thanks in advance.


Solution

  • You're pretty much SOL as far as using sendBeacon out of the box goes, as PUT and DELETE cannot be sent as you observed (only POST). For your XMLHttpRequest, Chrome is very explicit about saying, "hey, we used to send these synchronous XHR requests in beforeunload if you used a no-op loop, but we're not supporting that anymore":

    Failed to execute 'send' on 'XMLHttpRequest' [...] Synchronous XHR in page dismissal.

    Chrome is intentionally disallowing this behavior. You have no option except to modify the backend, i.e., set up an endpoint that will receive sendBeacon POST request like https://example.com/trigger-delete/ and trigger the DELETE call from the backend, or, if it's not your server, you'll actually have to set up a relay server you control to receive the POST (https://myrelay.com/forward-delete/)and then pass it along as a DELETE.

    sendBeacon is the only way you're getting out of this, as far as I can tell.