This is the 10th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

When we make the requirement of burying point, we may encounter the recording page residence time, which may be realized by sending a burying point request on the entry page and another one on the exit page.

However, we will find that sending an asynchronous request at unload or beforeunload will cause the request to be cancelled. So how do you send the request before the page closes?

What we did before

Possible methods used before are as follows:

  • Change to a polling request and send a dwell time every n seconds: this is very expensive and the time counts are not accurate enough
  • Change to SynchronizeXMLHttpRequestRequest: This can be done, but it will block the next page load and slow it down, not a good idea

The previous approach has its own shortcomings, so how to achieve?

sendBeacon

The navigator.sendbeacon () method is proposed to solve this problem. It can be used before the page is closed to send an asynchronous HTTP request with a small amount of data without affecting the next page load.

The API is introduced

const result = navigator.sendBeacon(url, data);
Copy the code

Its first argument is the interface address; The second argument is the data to send, which can be in ArrayBufferView, Blob, DOMString, or FormData format

The method returns true on success, false otherwise

The browser compatibility is fine

Maximum data size

As mentioned, sendBeacon can be used before the page is closed to send asynchronous HTTP POST requests with a small amount of data. How much is a small amount? StackOverflow

The maximum size is determined by the user agent (browser or otherwise) www.w3.org/TR/beacon/#… , you can test it this way:

var url = 'http://jsfiddle.net?sendbeacon';
var n = 65536; // sendBeacon size limit on Chrome V40 on Windows (2^16)

/ / http://stackoverflow.com/questions/14343844/create-a-string-of-variable-length-filled-with-a-repeated-character
// To get a string of length n+1 and content 'X', you can now just use 'X'. Repeat (n+1).
var data = new Array(n+1).join('X'); 

if(! navigator.sendBeacon(url, data)) { alert('data limit reached');
}
Copy the code

example

window.addEventListener("unload", sendData, false);

function sendData() {
  navigator.sendBeacon("/log", someData);
}
Copy the code

reference

  • Developer.mozilla.org/zh-CN/docs/…
  • www.w3.org/TR/beacon/#…
  • Stackoverflow.com/questions/2…