页面关闭前用fetch发送埋点请求最可靠方案是监听pagehide事件并设置keepalive: true,确保请求发出;兼容旧浏览器可降级使用navigator.sendBeacon。

页面关闭前用 fetch 发送埋点请求,关键在于避免请求被浏览器中断。默认情况下,fetch 是异步且无保证的,页面卸载(如刷新、关闭、跳转)会中止未完成的 fetch 请求。要提高成功率,需结合 beforeunload / pagehide 事件 + keepalive: true 选项。
使用 keepalive: true 确保请求发出
keepalive: true 告诉浏览器:即使页面即将卸载,也要尽力把请求发出去(适用于 POST/GET,且请求体不能太大,通常 ≤64KB)。这是目前最可靠的标准方案:
- 必须在
beforeunload或pagehide事件中调用 - 不支持 await,应忽略返回值或用
.catch()静默处理失败 - 服务端需能接收并快速响应(无需等待响应,浏览器只确保发出)
示例:
window.addEventListener('beforeunload', () => {
fetch('/api/track', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event: 'page_exit', url: location.href }),
keepalive: true // ? 关键
});
});
优先监听 pagehide 而非 beforeunload
pagehide 比 beforeunload 更现代、更可靠,尤其在移动端和后台标签页场景下:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
beforeunload在某些浏览器(如 Chrome)中已被限制,且可能触发烦人的“确定要离开吗?”提示 -
pagehide不会阻塞页面,且在页面进入 bfcache(后台缓存)时仍会触发,覆盖更多退出场景 - 建议同时监听两者,但以
pagehide为主
推荐写法:
const sendExitTrack = () => {
fetch('/api/track', {
method: 'POST',
body: JSON.stringify({ event: 'leave', time: Date.now() }),
headers: { 'Content-Type': 'application/json' },
keepalive: true
}).catch(() => {}); // 忽略网络错误
};
window.addEventListener('pagehide', sendExitTrack);
// 兜底(可选)
window.addEventListener('beforeunload', sendExitTrack);
补充策略:降级到 navigator.sendBeacon(兼容性更好)
如果目标环境需支持较老浏览器(如 IE11、旧版 Safari),或希望更高成功率,可用 navigator.sendBeacon() 替代 fetch:
- 专为离页上报设计,浏览器保证发送(即使页面已关闭)
- 只支持 POST,且数据必须是 ArrayBuffer / Blob / FormData / URLSearchParams
- 不支持自定义 header,Content-Type 固定为
text/plain或由浏览器自动设置
示例:
const data = new URLSearchParams();
data.append('event', 'leave');
data.append('url', location.href);
window.addEventListener('pagehide', () => {
navigator.sendBeacon('/api/track', data);
});
注意事项与常见误区
实际使用中容易忽略这些细节:
- 不要在 fetch 中 await 或依赖响应 —— 页面卸载后 JS 执行随时终止
- 避免在事件回调里做复杂计算或异步等待,应立即发起请求
- 埋点字段尽量轻量,避免序列化大对象;keepalive 对请求大小有限制
- 本地开发时,Chrome 的“取消请求”行为可能让你误判失败 —— 可在服务端打日志验证是否收到
- 单页应用(SPA)中,路由跳转不触发 pagehide/beforeunload,需额外监听路由变化并主动上报

















