Closing Chrome window not sending data with sendBeacon in unload event handler

5.2k Views Asked by At

I am trying to send data when the window closes to prevent 2 people from editing and overwriting each others data. Currently I am using a sendBeacon within a unload event handler.

FireFox:

  • Refresh: Works
  • Back button: Works
  • Close window: Works

Chrome:

  • Refresh: Works
  • Back button: Works
  • Close window: Doesn't work

Here is my code

function sendDataOnClose(edit,trans){

    var url = "../../save.php"; //This has a post request handler and works properly with other functions for saving data

    const data = JSON.stringify
    ({
      "translations": trans,
      "edit": edit
    });

    navigator.sendBeacon(url, data);
  }

function handleClose(){
    if(edit){
      console.log("sending a false when edit is: "+ edit)
      sendDataOnClose(false, translations);
    }
  }

window.addEventListener('unload', handleClose); 
2

There are 2 best solutions below

2
mitchellcarroll On

The latest sendBeacon documentation on MDN, states "The navigator.sendBeacon() method asynchronously sends a small amount of data over HTTP to a web server. It’s intended to be used in combination with the visibilitychange event (but not with the unload and beforeunload events)."

To use the visibilitychange event like suggested, you could

document.addEventListener('visibilitychange', function() {
  if (document.visibilityState === 'hidden') {
    navigator.sendBeacon(handleClose);
  }
});

I have experienced similar issues with trying send data on the unload event. Is the user base all on desktop? Mobile devices don't reliably fire the unload event. The Page Lifecycle API provides the visibility change event and the pagehide events which could be used together to get closer to your desired result.

The Page Lifecycle API attempts to solve this problem by: Introducing and standardizing the concept of lifecycle states on the web. Defining new, system-initiated states that allow browsers to limit the resources that can be consumed by hidden or inactive tabs. Creating new APIs and events that allow web developers to respond to transitions to and from these new system-initiated states. source

The issue you are experiencing is likely more of an issue without how browsers suspend pages or discard them entirely. Unfortunately, browsers are not unified on how they do this, and to add to the complexity there is different behavior on desktop vs. mobile.

There are several threads that dive in deeper to this issue if you are interested. Until browsers standardize on this, I'm not sure there is an easy answer, such as "use x event".

Issue filed on Page Visibility

Issue on MDN's strints about sendBeacon

4
AudioBubble On

Thanks to hackers, many other things are removed for security reasons.

I noticed your question had the PHP tag as well; I will give you a, not good idea, but a functional one. Avoid on-close-page handles even JavaScript or frameworks just post with JavaScript a table database where you store time() and an target id then if timeout is maybe more than 30 sec you set then you will remove from table that stuff, and you will know that page isn't still working (translation: use a server "online users" idea (bad but necessary one like anything generates lots of traffic in an app).

Using these in JavaScript in the side client is bad idea and you open gates for bad guys that will exploit your app.