Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sendBeacon request stuck as "(pending)" when attached to unload event

Tags:

javascript

When I call navigator.sendBeacon directly in the console, I immediately see the request in the Chrome dev tools Network pane complete successfully.

When I use code like what's below to attach sendBeacon to the beforeunload event and then navigate away from the page, I see a row added to the Network pane but its status stays stuck at "(pending)" and never sends.

What am I doing wrong?

  window.addEventListener('beforeunload', function() {
    navigator.sendBeacon(
      'https://www.example.com/sendBeacon-data-collector',
      'Sent by a beacon!');
  }, false);
like image 406
xnx Avatar asked Oct 14 '16 20:10

xnx


2 Answers

You say that the connection is stuck at "pending" and that it never sends. If it did not send, the connection would not at all show in the network pane, so this confirms that it does indeed send.

As for the status being stuck at "pending" that seems to be expected behaviour (a claim that I established empirically by observation only). By definition the sendBeacon command is not expecting an answer, so I assume that it's just normal that the browser does not show if the connection worked or not as it never reads a possible reply from the server (pure speculation on my part).

Anyway: I've got a sendBeacon in my web app that saves the last data to the database which is working fine in spite of the "pending" status prevailing. So if your data does not arrive, the problem may lie somewhere else.

For instance you need to make sure you send the data in the right format. In order to make it compatible with a script reading data from an HTML form, you cannot simply send a JSON string, but you need to put the string into formdata (otherwise you can only get it from raw post data on server side)

Example:

    var fd = new FormData();
    fd.append('data', JSON.stringify(beaconData));
    navigator.sendBeacon("inc/php/saveData.php", fd);

Also you need to be aware that sendBeacon always sends the data via POST parameters. If you want to use GET you need to add the data yourself in the url.

like image 104
Eric J. Francois Avatar answered Oct 28 '22 14:10

Eric J. Francois


I had this same problem. I had a Node/Express server that I was using to collect the record of the request. I was testing with an without the data.

The data can be sent as ArrayBuffer, ArrayBufferView, Blob, DOMString, FormData, or URLSearchParams object. So, that was not the issue.

The problem was in my server. I was using app.get( ) to check for the request instead of app.post( ).

ALL sendBeacon requests are sent via POST.

They will always appear as pending in the Chrome dev tools network tab. They will always show that there was a text/html response which is empty.

The sendBeacon request will be sent though via POST. It can be triggered via "unload" OR "beforeunload".

like image 45
Steve Griffith Avatar answered Oct 28 '22 13:10

Steve Griffith