beacon api是浏览器原生提供的卸载前可靠上报机制,支持pagehide等全场景,自动异步、不阻塞卸载,仅限post且无自定义headers,需服务端适配raw body解析。

Beacon API 是浏览器原生提供的、专为页面卸载场景设计的数据上报机制,能可靠地在用户关闭页面、跳转、刷新或浏览器进程终止前发送少量埋点数据,且不阻塞页面卸载流程。
为什么用 Beacon 而不是 fetch 或 XMLHttpRequest
普通异步请求(如 fetch)在页面卸载时会被浏览器主动中止,导致数据丢失;而 XMLHttpRequest 同步调用虽能发出去,但会冻结 UI、延长卸载时间,已被现代浏览器弃用或限制。Beacon 的核心优势在于:它由浏览器底层保障「尽力送达」,不参与页面生命周期的同步等待,也不影响用户体验。
- 自动异步、无感知:调用
navigator.sendBeacon(url, data)后立即返回true/false,无需 await 或回调 - 兼容卸载全场景:支持
beforeunload、pagehide、unload,甚至浏览器崩溃前的最后机会(部分浏览器支持) - 仅支持 POST 请求,且 payload 类型受限:推荐用
ArrayBuffer、Blob、FormData或纯字符串(如 JSON 字符串),不支持设置自定义 headers
典型使用方式:监听 pagehide + sendBeacon
pagehide 比 beforeunload 更可靠(尤其在安卓 Chrome 的后台标签页、iOS Safari 的预加载场景中),是推荐的触发时机。注意避免重复发送,可结合 event.persisted 过滤 bfcache 场景:
window.addEventListener('pagehide', (event) => {
if (event.persisted) return; // 页面进入缓存,无需上报
<p>const data = JSON.stringify({
type: 'page_exit',
url: window.location.href,
duration: performance.now() - startTime,
timestamp: Date.now()
});</p><p>// 发送成功返回 true,失败返回 false(通常因跨域或数据过大)
const sent = navigator.sendBeacon('/log', data);
if (!sent) {
// 可选降级:记录到 localStorage,下次打开时补报(需业务权衡)
}
});</p>
服务端接收注意事项
Beacon 发起的请求 Content-Type 默认为 text/plain,后端需能正确解析原始请求体(非标准表单或 JSON):
- Node.js(Express)示例:用
express.raw({ type: '*/*' })中间件接收原始 body - Java(Spring Boot):用
@RequestBody byte[]或InputStream读取原始字节流 - Nginx:确保未因请求头缺失(如无
Content-Type)而拦截或限流 - 注意:Beacon 不支持自定义 header,所以不能带
Authorization或X-Trace-ID,如需鉴权/追踪,应将必要字段编码进 URL 参数或请求体
常见问题与规避建议
Beacon 并非 100% 可靠(例如极端低内存、强杀进程时仍可能失败),实际埋点需配合容错策略:
- 数据体积控制:单次 Beacon 数据建议 ≤ 64KB,超大会被静默截断或拒绝
-
避免重复上报:在
pagehide中设置标记位(如window.__beaconSent = true),并在beforeunload中检查,防止多事件叠加触发 - 不依赖响应:Beacon 无回调,无法知道是否送达,切勿在 Beacon 后执行清理逻辑(如清 localStorage)
-
兼容性兜底:IE 完全不支持,Safari 11.1+ 支持;可检测
'sendBeacon' in navigator,降级为image打点(GET 请求)或延迟 100ms 的 fetch(仅作尽力尝试)
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











