闽公网安备 35020302035485号
// 推荐使用 'pagehide' 事件,它比 'unload' 更可靠
window.addEventListener('pagehide', (event) => {
// event.persisted 为 true 表示页面进入了往返缓存 (bfcache),并未真正卸载
// 这种情况下我们通常不发送信标
if (event.persisted) {
return;
}
const analyticsData = {
timeOnPage: Math.round(performance.now()),
lastAction: 'close_tab',
};
// 将数据转换为 Blob,这是 sendBeacon 支持的格式之一
const blob = new Blob([JSON.stringify(analyticsData)], {
type: 'application/json; charset=UTF-8',
});
// 堆代码 duidaima.com
// 使用 sendBeacon 发送数据
// 该方法会返回 true (成功加入队列) 或 false (数据过大或格式错误)
const success = navigator.sendBeacon('/log-analytics', blob);
if (success) {
console.log('分析日志已成功加入发送队列。');
} else {
console.error('无法发送分析日志。');
}
});
3.同样无法处理响应:和 sendBeacon 一样,由于页面已经关闭,我们无法在前端读取或处理服务器返回的响应
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
return;
}
const draftContent = document.getElementById('editor').value;
if (!draftContent) return;
const draftData = {
content: draftContent,
timestamp: Date.now(),
};
// 堆代码 duidaima.com
// 使用 fetch 和 keepalive: true
// 注意:即使请求成功,这里的 .then 和 .catch 也可能不会执行,因为页面正在卸载
try {
fetch('/api/drafts/save', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(draftData),
// 这是关键!
keepalive: true,
});
console.log('保存草稿的请求已提交。');
} catch (e) {
// 这个 catch 块很可能不会捕获到网络错误
console.error('提交保存草稿请求时发生错误:', e);
}
});
如何选择?