这是我参与「第四届青训营 」笔记创作活动的第2天
项目简介
这次参加字节青训营,大项目选择的是前端监控系统。前端监控系统可以自动收集、上报、存储Web页面关键数据。今天这篇文章主要是配置上报方法。
上报方法
navigator.sendBeacon() 方法可用于通过HTTP POST将少量数据 异步传输到 Web 服务器。
- 语法
navigator.sendBeacon(url, data);
- 参数
url 参数表明 data 将要被发送到的网络地址。
data 参数是将要发送的 ArrayBuffer、ArrayBufferView、Blob、DOMString、FormData 或 URLSearchParams 类型的数据。
上报时机
网站通常希望在用户完成页面浏览后向服务器发送分析或诊断数据,最可靠的方法是在 visibilitychange 事件发生时发送数据:
document.addEventListener('visibilitychange', function logData() {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('/report', data);
}
});
- 避免使用
unload和beforeunload
过去,许多网站使用 unload 或 beforeunload 事件以在会话结束时发送统计数据。然而这是不可靠的,在许多情况下(尤其是移动设备)浏览器不会产生 unload、beforeunload 或 pagehide 事件。下面列出了一种不触发上述事件的情况:
- 用户加载了网页并与其交互。
- 完成浏览后,用户切换到了其它应用程序,而不是关闭选项卡。
- 随后,用户通过手机的应用管理器关闭了浏览器应用。
上报格式
sendBeacon支持的参数类型里面不包含json格式,这意味着我们要使用其他的类型进行数据上报。
在这里则需要保证 Content-Type 为以下三种之一:
application/x-www-form-urlencoded
如果用 Blob 发送数据,这时需要我们手动设置 Blob 的 type,一般设置为 application/x-www-form-urlencoded。
const reportData = (url, data) => {
const blob = new Blob([JSON.stringify(data), {
type: 'application/x-www-form-urlencoded',
}]);
navigator.sendBeacon(url, blob);
};
text/plain
如果数据类型是 string,则可以直接上报,此时该请求会自动设置请求头的 Content-Type 为 text/plain。
const reportData = (url, data) => {
navigator.sendBeacon(url, data);
};
multipart/form-data
可以直接创建一个新的 Formdata,此时该请求会自动设置请求头的 Content-Type 为 multipart/form-data。
const reportData = (url, data) => {
const formData = new FormData();
Object.keys(data).forEach((key) => {
let value = data[key];
if (typeof value !== 'string') {
// formData只能append string 或 Blob
value = JSON.stringify(value);
}
formData.append(key, value);
});
navigator.sendBeacon(url, formData);
};
由于我们需要上传的类型,有数组、对象,所以我们使用text/plain,通过JSON.stringify操作,把所有数据转换成文本类型,交给后端进行处理。