Beacon API 彻底解决了我请求丢失的困扰: 不再漏埋点、不再丢错误、不再怀疑请求有没有到服务端。 那些“匆匆关页/迅速跳转”的场景里,你的追踪请求终于能活着抵达。
我花了好几周排查线上数据看板里追踪请求丢失的问题。前几天还像专业选手一样稳定收集用户行为,没多久请求掉得更快了。
每当用户意外离开页面,我用的 fetch() 请求就会在半路被意外取消。
仔细一看,锅不在业务逻辑,而在 JavaScript 的运行模型:浏览器决定终止标签页时,不会向你的脚本请示。
于是,我精心构造的埋点请求,还没抵达服务器就中道崩殂,数据自然缺斤少两。
解决之道:navigator.sendBeacon()
这时我发现了一个自 2014 年就存在、却少有人用的 API:navigator.sendBeacon()。它为一个目标而生:在浏览器“收摊”前,把数据安全送走。
和 fetch() 不同,Beacon 不等待响应、也不阻塞页面离开。 它会把请求排队,并在后台传输——即使你的 JavaScript 已经停了也照样发。
// 这种写法在页面卸载时可能失败
window.addEventListener('beforeunload', () => {
fetch('/analytics', {
method: 'POST',
body: JSON.stringify({ event: 'page_exit' })
}); // ❌ 可能被取消
});
// 这种更稳
window.addEventListener('beforeunload', () => {
navigator.sendBeacon('/analytics',
JSON.stringify({ event: 'page_exit' })
); // ✅ 至少能成功进入队列
});
当用户迅速跳转或直接关页时,差异就非常明显:
浏览器往往会在卸载阶段取消 fetch,以保证更快离开;Beacon 则是专为此刻设计。
可靠性:数字会说话
我看了下可靠性数据,结果挺“长见识”的:
navigator.sendBeacon()在页面切换时,送达率可达 95.8% ;- 传统
fetch()大约 掉到 84.9%。 - 在移动端,差距更大:桌面端几乎“近乎完美”,而移动端的
fetch往往受激进内存回收、应用切后台等影响更明显。
Beacon API 就是为这种小而关键的负载而生:
- 更可靠:请求进入浏览器原生队列,可穿越卸载窗口;
- 不阻塞:不会拖慢导航;
- 更简单:无需复杂兜底或大而全的埋点库。
载荷边界:64KB 严限制,且有总量配额
需要注意:Beacon 单次请求有 64KB 硬限制。 不仅是“每次”,队列里多条 beacon 还会共享这 64KB 预算。
// ✅ 正好 64KB,可排队
navigator.sendBeacon('/log', 'A'.repeat(65536));
// ❌ 超限会直接返回 false
navigator.sendBeacon('/log', 'A'.repeat(65537));
sendBeacon() 的返回值表明是否成功进入队列(true/false)。务必检查它并做兜底:
const ok = navigator.sendBeacon('/analytics', data);
if (!ok) {
// 兜底:退回到 fetch 或把数据拆小
fetch('/analytics', {
method: 'POST',
body: data
});
}
Content-Type 的小坑
一个让人挠头的限制:Beacon 不支持自定义请求头。 传字符串时,浏览器默认用 **text/plain**,你的 JSON 在服务端会被当作纯文本。
可以用 Blob 曲线救国,但会触发 CORS 预检:
const data = { event: 'click', count: 42 };
const blob = new Blob([JSON.stringify(data)], {
type: 'application/json'
});
navigator.sendBeacon('/analytics', blob);
// ⚠️ 会触发 CORS 预检;服务端必须正确处理
多数团队会保留 text/plain,在服务端自己解析 JSON,以避免跨域预检的额外开销。
不止是埋点:错误上报 & 用户行为
Beacon 不是只能做“页面退出埋点”。它也非常适合实时错误上报,而且不阻塞 UI:
window.addEventListener('error', (event) => {
const errorData = {
message: event.message,
filename: event.filename,
line: event.lineno,
stack: event.error?.stack,
timestamp: Date.now()
};
navigator.sendBeacon('/errors', JSON.stringify(errorData));
});
而在用户交互追踪上,Beacon 是“发了就忘”的好工具:
document.addEventListener('click', (event) => {
const clickData = {
element: event.target.tagName,
x: event.clientX,
y: event.clientY,
timestamp: Date.now()
};
navigator.sendBeacon('/interactions', JSON.stringify(clickData));
});
现代替代:fetch + keepalive
另一条近年流行的路,是给 fetch() 加 **keepalive**:
fetch('/analytics', {
method: 'POST',
body: JSON.stringify(data),
keepalive: true,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
}
});
这样既有 Beacon 的卸载期可靠性,又保留 fetch 的灵活性:自定义头、丰富方法、可处理响应等。 到 2025 年,浏览器支持已相当好(例如 Firefox 133 让 keepalive 进入“基线”阵营)。
何时用谁?
选 navigator.sendBeacon():
- 轻量埋点/日志
- 页面退出/会话收尾
- 错误上报/诊断
- 追求最大兼容与最低心智负担
选 fetch({ keepalive: true }):
- 需要自定义头/鉴权
- 需要处理响应或复杂 HTTP 配置
- 你需要更通用的请求能力
兼容性:基本都被覆盖了
Beacon API 在现代浏览器里支持度很稳,大约 92% 的兼容覆盖:
- Chrome 39+、Firefox 31+、Safari 11.1+、Edge 14+
- IE 是主要缺口,但在 2025 年 基本不再是现实问题。
想要最大覆盖,就加特性检测兜底:
if (navigator.sendBeacon) {
navigator.sendBeacon('/log', data);
} else {
// 退回到 XHR(注意:示例为同步 XHR,按需替换)
const xhr = new XMLHttpRequest();
xhr.open('POST', '/log', false);
xhr.send(data);
}
总结
Beacon API 彻底解决了我请求丢失的困扰: 不再漏埋点、不再丢错误、不再怀疑请求有没有到服务端。 那些“匆匆关页/迅速跳转”的场景里,你的追踪请求终于能活着抵达。
AI大模型学习福利
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
四、AI大模型商业化落地方案

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量
JavaScript Beacon API 实战指南

被折叠的 条评论
为什么被折叠?



