场景:前端埋点,网页刷新或者关闭的时候调用异步请求
常规方案
- 直接发送 xhr 请求
我们会优先想到监听页面的unload或者beforeunload事件,在事件回调里使用XMLHttpRequest发送异步请求。
但是由于是xhr请求是异步发送,很可能在它即将发送的时候,页面已经卸载了
,从而导致发送取消或者发送失败
。异步请求响应返回后,由于页面和相关资源已经卸载,会引起function not found的错误,
导致数据统计有错
Navigator.sendBeacon()
浏览器引入的sendBeacon方法,发出的是异步请求,但是请求是作为浏览器任务执行的,与当前页面是脱钩的。因此该方法不会阻塞页面卸载流程和延迟后面页面的加载
基本用法
navigator.sendBeacon(url, data);//true||false
url 就是上报地址,data 可以是 ArrayBufferView,Blob,DOMString 或 Formdata
sendBeacon 如果成功进入浏览器的发送队列后,会返回true;如果受到队列总数、数据大小的限制后,会返回false。返回ture后,只是表示进入了发送队列,浏览器会尽力保证发送成功,但是否成功了,无法判断。
sendBeacon方法具有如下特点:
1.发出的是异步请求,并且是POST请求,后端解析参数时,需要注意处理方式;
2.发出的请求,是放到的浏览器任务队列执行的,脱离了当前页面,所以不会阻塞当前页面的卸载和后面页面3.的加载过程,用户体验较好;
4.只能判断出是否放入浏览器任务队列,不能判断是否发送成功;
5.Beacon API不提供相应的回调,因此后端返回最好省略response body
传json的写法
//例
let data={
a:"测",
b:"试"
}
//创建blob对象,并设置请求头
const blob = new Blob([JSON.stringify(data)], {
type: 'application/json; charset=UTF-8',
});
//调用接口,并传送数据
navigator.sendBeacon(url, blob);
效果同下面axios方法一样
axios.post(url,data)
网友评论