onbeforeunload 中发送 Ajax 请求基本不可靠,因浏览器会中断未完成请求;推荐使用 navigator.sendBeacon() 或 pagehide 等更可靠的替代方案。

在页面卸载前用 window.onbeforeunload 发送 Ajax 请求,**基本不可靠,也不推荐**。因为浏览器会中断未完成的网络请求,尤其当用户快速关闭标签页或刷新时,请求大概率发不出去或被丢弃。
为什么 onbeforeunload 里发 Ajax 几乎无效
onbeforeunload 的设计目标是提示用户“是否离开”,不是执行异步操作。它的执行环境非常受限:
- 浏览器不等待异步任务(如
fetch或XMLHttpRequest)完成就直接卸载页面 - 现代浏览器(Chrome、Firefox、Safari)对
onbeforeunload中的网络请求有主动终止策略 - 即使使用同步 XMLHttpRequest(
async: false),也已被多数浏览器废弃或禁用,且会阻塞 UI,体验极差
更可靠的替代方案:使用 navigator.sendBeacon()
这是专为页面卸载前发送小量数据设计的 API,异步但保证发出(只要浏览器支持):
- 自动使用 HTTP POST,无需手动处理响应
- 在页面卸载期间仍能排队发送,不阻塞卸载流程
- 兼容性好(Chrome 37+、Firefox 31+、Edge 14+、Safari 11.1+)
用法示例:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
window.addEventListener('beforeunload', function (e) {
// 发送轻量清理数据(如用户停留时长、退出状态)
const data = JSON.stringify({ action: 'leave', timestamp: Date.now() });
navigator.sendBeacon('/api/track', data);
});
注意:sendBeacon() 只支持 text/plain、application/x-www-form-urlencoded 和 multipart/form-data 类型;若需 JSON,服务端要能解析原始 body。
补充策略:关键状态提前保存
不要依赖“最后时刻”发送——把重要清理逻辑前置:
- 监听
visibilitychange:页面失焦或切到后台时就提交一次 - 监听
pagehide(比beforeunload更可靠):页面隐藏时触发,包括前进/后退、标签切换 - 定时上报 + 本地缓存:例如每 30 秒存一次草稿或状态,关页前再 flush 本地 pending 数据
示例:
window.addEventListener('pagehide', function (e) {
if (!e.persisted) { // 非缓存还原(即真实卸载)
navigator.sendBeacon('/api/cleanup', getPendingData());
}
});
服务端配合建议
清理请求失败是常态,服务端应具备容错能力:
- 幂等设计:同一用户的多次“退出”请求可重复处理,不报错
- 超时兜底:用户长时间无操作后,服务端主动清理 session 或临时资源
- 客户端打时间戳 + 去重 ID:避免因重发导致脏数据
不复杂但容易忽略。

















