AJAX on web page unloading

JavaScript-logo

TL;DR On page unload AJAX network requests are sent by all browsers if – contrary to the general advice – the synchronous flavour of  XMLHttpRequest (SJAX) is used.

 The Problem of sending goodbye data on page unload

occurs often that a single page web application (SPA) needs to change the state in its cloud end (clean up resources, close network connections…) when a user quits the application (i.e. she closes the browser window).
The obvious choice is to subscribe for the DOM window’s unload and/or beforeunload events with handler methods and trigger a remote signal on a server via XMLHttpRequest (i.e. AJAX). The result of that signalling is usually of no interest to the SPA front end (browser page).
However what can be done in these handlers has always depended on the various browser implementations.

The beforeunload Event Handler

can prompt the user to remain in the SPA showing a native UI dialog while JavaScript execution is halted. For creating network requests the same constraints as with the unload handler apply, except for the Chrome browser.

In the unload Event Handler

the UI is already gone. Therefore UI operations (alert, window.open,…) do not make sense here. How much JavaScript execution time remains is unknown. However to deduct that operations in here have to be fast and avoid all blocking JavaScript instructions all together is wrong!
Tests (see the table below) show that many browsers do not issue network requests if done asynchronously.

The Solution

is to use AJAX without the first ‘A’ or S(ynchronous)JAX if there were such a thing. Thus simply setting the async flag of the XMLHttpRequest.open method to false ensures the network request is fired by all browsers. But never mind about that blockingness of the JavaScript instruction, because we are not interested in the response anyway!

A Test Case

is kept in jQuery and can be found under jquery/test/data/ajax/onunload.html

Test Results

v.10v.36v.30v.7
AJAX (async = true)okokfails?
AJAX (async = true)
after dismissed a beforeunload prompt
okfails sometimesfails?
SJAX (async = false)okokokok