javascript

beforeunload workaround using preventDefault to do a GET request


My website is creating a file in the backend. Once the user leaves or refreshes the page that data is deleted with a GET request:

window.addEventListener('beforeunload', function () {
    delete_file();
});

This works locally but in some browsers/builds, if you refresh the page, beforeunload doesn't trigger. The workaround:

window.addEventListener('beforeunload', function (event) {
    event.preventDefault();
    delete_file();
});

Now it gives a popup on whether you want to leave with unsaved changes. But if I press cancel and stay on the page, this still runs and deletes the file. I've tried:

I don't care if the user gets the "you may lose changes" prompt. This data is stored in the backend. I want it to delete the file when the user refreshes/leaves/exits the page and for that to work on all systems.


Solution

  • I have a website that is creating a file in the backend to store data.

    Then it is also the job of the backend to delete that file when deemed necessary. And as usual in building robust client-server systems, the server must not rely on any particular client behaviour to do its job.

    The client (webpage in browser) may be gone at any moment, for any reason: a navigation without executing onBeforeUnload, a killed browser process, a JS exception having crashed your web application, or simply a (mobile) internet connection being lost. You cannot rely on receiving a signal from the client that it's gone.

    The only viable approach is to use the absence of a (keep-alive) signal as the indicator that a client is gone; implemented with a timeout on any sort of connection. Send requests to the server to not delete the file at a regular interval. When receiving them, the server keeps the file around for another period, then schedules it for deletion.

    You may choose a rather long timeout, then optimise the system to delete the file earlier upon request. This could happen when the browser tells you that the tab is about to be closed; it could happen when the user opens their next session. Still, the default (fallback) solution must be implemented in the server itself only, to ensure the file is deleted after some time even with an uncooperative client.