navigator.sendbeacon比ajax更可靠,因其专为页面卸载设计:异步无阻塞、不等待响应、浏览器保证入队后尽力发送;需在pagehide中调用,数据用urlsearchparams或formdata构造,控制在64kb内,并配合前端去重、服务端幂等和localstorage降级。

别用 AJAX 做离开页上报,直接用 navigator.sendBeacon —— 它专为这个场景设计,不阻塞、不中断、浏览器兜底发送。
为什么 sendBeacon 比 AJAX 更可靠
AJAX(fetch / XHR)在页面卸载时大概率被浏览器中止:请求刚发出去,tab 就关了,连接断开,服务端收不到。而 sendBeacon 是浏览器级机制,数据一提交就进后台发送队列,哪怕页面已关闭,浏览器仍会在进程退出前尽力发出。
- 不等待响应,不触发 CORS 预检,只支持简单请求头(
text/plain、application/x-www-form-urlencoded、multipart/form-data) - 返回
true表示成功入队(非送达),false表示失败(如不支持或内存不足) - 完全异步,零感知延迟,不影响跳转或关闭体验
正确监听离开时机,避开失效事件
别只依赖 unload 或 beforeunload:unload 在现代浏览器中已被部分禁用;beforeunload 可能被用户取消,且不保证执行完成。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
首选
pagehide:覆盖刷新、关闭、前进后退、后台切换等所有卸载路径,事件一定触发 -
备选
visibilitychange:监听document.visibilityState === 'hidden',适合曝光类埋点 - 避免在
unload中调用,兼容性差且不可靠
数据构造与发送要点
sendBeacon 接收的 data 类型有限制,不能直接传 JSON 对象,需序列化为支持格式:
- 推荐用
URLSearchParams:自动编码,适配application/x-www-form-urlencoded - 也可用
FormData(适合含文件字段的场景,但注意体积) - 若需 JSON 字符串,可作为字段值传入:
params.append('payload', JSON.stringify(obj)) - 单次 payload 控制在 64KB 内(Chrome 限制),超限会静默失败
健壮性必须做的三件事
sendBeacon 不是“发了就完事”,要防重复、防失败、防丢数:
-
前端去重:用闭包变量或
WeakMap标记是否已触发,避免pagehide+visibilitychange同时触发两次 -
服务端幂等:按
session_id + timestamp或payload hash去重,接受可能的多次到达 -
降级 fallback:检测
!navigator.sendBeacon或返回false时,可存入localStorage,下次打开页面补报
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










