Navigator.sendBeacon:解决页面关闭可靠地上报数据
使用场景
为了满足页面统计需要,我们往往需要在页面关闭前(实际时页面卸载前),调用unload方法向服务器上报数据。
基于XMLHttpRequest异步方案
异步方案时在unload,或者beforeunload使用基于XMLHttpRequest Ajax异步请求,但此异步请求存在不可靠。因为如果请求还没有完成,页面已经卸载了,可能导致数据上传不成功。
同步方案
因为异步方案上传数据不可靠,所以添加一些同步的耗时函数,保证请求完成后才返回。如:
- setTimeout检查请求的返回结果
- 创建几秒钟的 no-op 循环来延迟卸载
- 创建一个图片元素并设置它的 src 属性的方法来延迟卸载。
异步转同步示例:把xhr以同步方式打开,集opne的第三个参数
window.addEventListener('unload', logData, false);
function logData() {
    var client = new XMLHttpRequest();
    client.open("POST", "/log", false); // 第三个参数表明是同步的 xhr
    client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
    client.send(data);
}Navigator.sendBeacon
以上基于XHR的方式都有各自的问题,异步不可靠,同步耗时。这就是Navigator.sendBeacon要解决的问题。
sendBeacon方法是通过HTTP将少量数据异步传输到Web服务器,它的异步是将请求与当前页面线程脱钩,作为浏览器进程的任务,可以可靠把数据上报到服务器,并且阻塞当前页面的卸载流程。
语法
navigator.sendBeacon(url);
navigator.sendBeacon(url, data);参数说明:
- url:请求的地址
- data:可选,类型可以是ArrayBuffer,ArrayBufferView,Blob,DOMString,FormData和URLSearchParams
使用示例
document.addEventListener('visibilitychange', function logData() {
  if (document.visibilityState === 'hidden') {
    navigator.sendBeacon('/log', analyticsData);
  }
}); 
             
             
             
             
            