前端页面关闭前,上传监控数据的4个解决方案

前言

文章来源 在页面关闭时,前端上传监控数据的 4 个解决方案

同步 XMLHttpRequest

同步请求阻止代码的执行,这会导致屏幕上出现“冻结”和无响应的用户体验。

缺点:

  1. 用户体验差,会阻塞页面切换
  2. 只有旧版的浏览器支持
  3. 无法读取reponse的返回值

已经不建议使用了

img.src

创建一个<img>元素,并设置src。大部分的浏览器,都会延迟卸载当前页面,优先加载图像。

缺点:

  1. 数据传输不可靠,有可能浏览器卸载当前页面,直接杀掉图像请求
  2. 只能发起 GET 请求
  3. 数据大小有限制

通过 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。
注意返回值的时机:成功加入传输队列,而不是服务端的处理成功后的返回。

缺点

  1. 只能发起 POST 请求
  2. 无法自定义请求头参数
  3. 数据大小有限制 (Chrome 限制大小为 64kb)
  4. 只能在 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,
});
关于我
loading