前端页面关闭前,上传监控数据的4个解决方案
大熊•
前言
同步 XMLHttpRequest
同步请求阻止代码的执行,这会导致屏幕上出现“冻结”和无响应的用户体验。
缺点:
- 用户体验差,会阻塞页面切换
- 只有旧版的浏览器支持
- 无法读取
reponse
的返回值
已经不建议使用了
img.src
创建一个<img>
元素,并设置src
。大部分的浏览器,都会延迟卸载当前页面,优先加载图像。
缺点:
- 数据传输不可靠,有可能浏览器卸载当前页面,直接杀掉图像请求
- 只能发起 GET 请求
- 数据大小有限制
navigator.sendBeacon
通过 HTTP POST 请求,将少量数据使用异步的方式,发送到服务端。
function reportEvent() {
const url = 'http://xxx/test';
const data = JSON.stringify({
time: performance.now()
});
navigator.sendBeacon(url, data);
}
document.addEventListener('visibilitychange', function() {
if (document.visiblityState === 'hidden') {
reportEvent();
}
});
发送的时机
浏览器端自动判断合适的时机进行发送
是否会产生阻塞或影响页面性能?
不会产生阻塞,影响当前页面的卸载。
不影响下个新页面的加载,不存在性能问题。
另外,数据传输可靠。
语法
navigator.sendBeacon(url);
navigator.sendBeacon(url, data);
url
:接收请求的网络地址
data
:请求中携带的数据,数据格式可选:ArrayBuffer,ArrayBufferView,Blob,DomString,FormData,URLSearchParams
返回值
当浏览器将数据成功加入传输队列时,sendBeacon 方法会返回 true,否则返回 false。
注意返回值的时机:成功加入传输队列,而不是服务端的处理成功后的返回。
缺点
- 只能发起 POST 请求
- 无法自定义请求头参数
- 数据大小有限制 (Chrome 限制大小为 64kb)
- 只能在 window 事件 visibilitychange 和 beforeunload 中使用,其他事件中回调,会丢失数据。
fetch keepalive
标记 keepalive 的 fetch 请求允许在页面卸载后执行。
The keepalive option can be used to allow the request to outlive the page. Fetch with the keepalive flag is a replacement for the Navigator.sendBeacon() API.
const url = 'http://xxxx';
const data = JSON.stringify({
time: performance.now()
});
fetch(url, {
method: 'POST',
body: data,
headers: {
'Content-Type': 'application/json'
},
keepalive: true,
});
上一篇:webpack打包文件常见问题
下一篇:JS开发常用48种工具函数