需求:在用户关闭页面的的时候需要发送API请求,来记录用户已关闭页面的操作
对于 ajax 发起异步请求,若在发送过程中 刷新或关闭 浏览器,请求会被自动终止。
异步方式的 ajax 请求被浏览器自动取消,无法将数据正常推送到后台。
目前,谷歌浏览器已经不允许在页面关闭期间发起 同步 XHR 请求,建议使用 sendBeacon
或者 fetch
1、sendBeacon
navigator.sendBeacon()
方法可用于通过 HTTP 将少量数据 异步 传输到 Web 服务器。
官方链接:Navigator.sendBeacon() - Web API 接口参考 | MDN
// 通过 Blob 方式发送 JSON 数据
const blob = new Blob(
[JSON.stringify({ ... })],
{ type: 'application/json; charset=UTF-8' }
);
// 发送请求
navigator.sendBeacon(url, blob);
url
: 指定将要被发送到的网络地址;data
: 可选,是将要发送的 ArrayBuffer、TypedArray、Blob、String、FormData 或 URLSearchParams 类型的数据。return
: 返回值。当用户代理成功把数据加入传输队列时,sendBeacon()
方法将会返回true
,否则返回false
。
特点:
- 通过
HTTP POST
请求方式 异步 发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能; - 支持跨域,但不支持自定义
headers
请求头,这意味着:如果用户信息Access-Token
是作为请求头信息传递,需要后台接口支持url querystring
参数传递解析。 - 考虑其兼容性。
1、fetch
当使用 fetch()
请求时,如果把 RequestInit.keeplive
设置为 true
,即便页面被终止请求也会保持连接。
fetch(url, {
method: 'POST',
body: JSON.stringify({ ... }),
headers: {
'Content-Type': 'application/json',
"access-token": '...'
},
keepalive: true, // 页面被终止请求也会保持连接
});
推荐使用 Fetch API 实现
注意:
传输数据大小限制
:无法发送兆字节的数数据,我们可以并行执行多个keepalive
请求,但它们的 body 长度之和不得超过64KB
。无法处理服务器响应
:在网页文档卸载后,尽管设置keepalive 的 fetch 请求
可以成功,但后续的响应处理无法工作。所以在大多数情况下,例如发送数据信息,因为服务器只接收数据,并通常向此类请求发送空的响应。
浏览器关闭或刷新相关事件
# 浏览器关闭前
document.addEventListener("beforeUnload", () => {});
# 浏览器关闭,隐藏和tab切换
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
} else {
}
});
# 浏览器关闭
document.addEventListener("unload", () => {});