Beacon API 是浏览器提供的卸载前可靠上报机制,通过 navigator.sendBeacon() 发送 POST 数据,不阻塞页面关闭,支持 Blob、FormData 等格式但不支持自定义 headers,无回调且有 64KB 大小限制。
Beacon API 是浏览器提供的一种专门用于在页面卸载前发送数据的机制,它能确保请求发出且不阻塞页面关闭或跳转。 它不是普通的异步请求(如 fetch 或 XMLHttpRequest),而是“尽力而为”的可靠上报方式——即使用户已关闭标签页、刷新页面或导航离开,浏览器仍会在后台尝试发送数据。
当用户触发页面卸载(比如点击链接、关闭标签、刷新、前进后退)时,浏览器会中止所有未完成的 fetch / XHR 请求。即使你用了 fetch(...).catch(...) 或设置了 timeout,这些请求大概率根本没发出去,或者被静默取消。
Beacon 则不同:调用 navigator.sendBeacon() 后,浏览器承诺将数据加入发送队列,并在当前页面彻底卸载前尽可能发出——不等待响应,不阻塞卸载流程,也不受页面状态影响。
核心方法是 navigator.sendBeacon(url, data),它只支持 POST 请求,且 data 类型受限:
ArrayBufferView(如 Uint8Array)、Blob、FormData、URLSearchParams、字符串(自动设为 text/plain)简单示例:
// 记录用户停留时长(页面即将离开时上报)
window.addEventListener('beforeunload', () => {
const data = JSON.stringify({
page: window.location.href,
duration: performance.now() - startTime
});
// 自动以 text/plain 发送
navigator.sendBeacon('/log', data);
});

它不是万能的,实际使用中要注意这些边界:
如果需要更高可靠性或更复杂数据格式,可组合使用:
sendBeacon
fetch(..., { keepalive: true })(部分浏览器支持,行为类似 beacon)xmlhttp.open(..., false))——但会明显卡住页面,仅作极端保底,不推荐常规使用检测支持性也很简单:
if (navigator.sendBeacon) {
navigator.sendBeacon('/log', payload);
} else {
// 尝试 fetch keepalive 或其他方案
}
基本上就这些。Beacon 不复杂但容易忽略,适合埋点、性能打点、用户行为收尾上报等「发了就好,不必等回执」的场景。