首页 > IT职业 > > 在页面关闭时,前端上传监控数据的4个解决方案
本文以 “前端监控上报数据” 的业务场景,重点解析在 页面实例关闭 时,如何将监控数据上传到服务端的解决方案。
其中,涉及到4种方案,分别为:
const data = JSON.stringify({
time: performance.now()
});
var xhr = new XMLHttpRequest();
// 第三个参数false,表示当前请求是同步
xhr.open('post', 'http://api.wangxiaokai.vip/test', false);
xhr.setRequestHeader('content-type', 'application/json');
xhr.onreadystatechange = function() {
// 发送成功后,页面已销毁,所以这里执行不了
}
xhr.send(data);
复制代码
同步请求阻止代码的执行,这会导致屏幕上出现“冻结”和无响应的用户体验。
然而,在新版的chrome(版本号大于80)已经不支持。
以下是官方的公告片段:
Chrome now disallows synchronous calls to
XMLHTTPRequest()during page dismissal when the page is being navigated away from or is closed by the user. This applies tobeforeunload,unload,pagehide, andvisibilitychange.
详细解释可阅读 Disallow Synchronous XMLHTTPRequest\(\) in Page Dismissal[2]
reponse的返回值创建一个<img>元素,并设置src。大部分的浏览器,都会延迟卸载当前页面,优先加载图像。
var data = JSON.stringify({
time: performance.now()
});
const img = new Image();
img.src = `http://api.wangxiaokai.vip/test?${JSON.stringify(data)}`;
复制代码
GET请求通过HTTP POST请求,将少量数据使用异步的方式,发送到服务端。
function reportEvent() {
const url = 'http://api.wangxiaokai.vip/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请求64kb)visibilitychange和beforeunload中使用,其他事件中回调,会丢失数据。
MDN web docs的描述如下 :
The
keepaliveoption can be used to allow the request to outlive the page. Fetch with thekeepaliveflag is a replacement for the `Navigator.sendBeacon()`[3] API.
标记keepalive的fetch请求允许在页面卸载后执行。
const url = 'http://api.wangxiaokai.vip/test';
const data = JSON.stringify({
time: performance.now()
});
fetch(url, {
method: 'POST',
body: data,
headers: {
'Content-Type': 'application/json'
},
keepalive: true,
});
复制代码

关于本文:
来源:我是leon
https://juejin.cn/post/7106365076197605413
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69979225/viewspace-3126895/ ,如需转载,请注明出处,否则将追究法律责任。