I'm trying to make a network request when a user closes their browser or tab. If you search here on stackoverflow, you'll find one method is to use beforeunload
or window.onbeforeunload
. If you return undefined from your onbeforeunload
callback, no dialog will appear and your code will be executed.
However, this is not intended to make network requests but to confirm with the user whether they mean to leave the page. For example, if a user has filled out a long form and you want to confirm with them that they didn't close on accident.
It follows that you shouldn't rely on onbeforeunload
because there isn't any guarantee that the request will complete. It was apparently not designed to execute requests. I have found many such answers directing people away from onbeforeunload
and instead to Navigator.sendBeacon
:
The browser API Navigator: sendBeacon was designed for this purpose. sendBeacon
accepts a url
and an optional data
parameter which it will POST to. There are no options to either use a different HTTP method such as GET or DELETE nor does it accept a callback where you could use the fetch
API to do so. You are limited to only posting data.
On the MDN docs for Navigator.sendBeacon
, it even mentions this:
Note: For use cases that need the ability to send requests with methods other than POST, or to change any request properties, or that need access to the server response, instead use the fetch() method with keepalive set to true.
Does this mean that making requests in onbeforeunload
is indeed reliable so long as you use the fetch
API with keepalive:true
? Which should be used? If I need to make a non-POST request, set headers, or access the request's response is keepalive:true
with fetch enough?
The MDN docs for beforeunload event essentially say that it's not recommended to use this event for anything but preventing a user from losing data. If not beforeunload, what's the best way to reliably make a non-POST network request when a user closes a browser tab?
I know there are more robust ways of detecting this with websockets, but what's the client-only method that would work at least nearly as well as sendBeacon?