新闻详情

新闻详情

首页 / 资讯中心 / 详情

页面关闭前埋点丢失:sendBeacon验收

发布时间:2026/9/30 13:16:58来源:尧图网络
页面关闭前埋点丢失:sendBeacon验收
直答页面关闭时浏览器会取消未完成请求XHR 必丢。sendBeacon 交给后台排队更可靠但只保证发出不保证到达。最后一批访客的停留时长全是 1~2 秒——不是用户真的划走了是关闭页面前那一刻的「离开事件」根本没发出去。服务端只收到了进来的事件没收到离开的事件停留时长就被截断在最后一次活动上。不写长篇大论下面给一份可以直接复制到团队 Wiki 里的验收清单。一、为什么 XHR 在页面关闭时一定会丢浏览器在卸载页面时会做一件事取消所有还没完成的网络请求。你在beforeunload里发一个 XHR请求刚构造出来页面已经被关了请求被浏览器掐断。这不是网络问题也不是 SDK bug是浏览器故意的——它不想让一个即将销毁的页面继续占用网络。历史上大家的做法是在页面里塞一个 1×1 像素的图片把埋点参数拼在 src 上。图片请求是同步的浏览器会等它发出去再关页面。但这种做法在 HTTPS、跨域、大数据包时都不稳定现在已经被 W3C 的 Beacon API 正式取代。要理解这件事得先把页面关闭时的事件顺序理清楚。现代浏览器在页面离开时会依次触发 beforeunload、pagehide、unload 三个事件。beforeunload 原本用来弹「确定离开吗」的确认框但 Chrome 117 之后对这类弹窗加了严格限制移动端浏览器更是经常直接不触发它unload 则在页面真正卸载时触发可一旦走到这里页面资源随时可能被回收再发请求已经太晚。pagehide 夹在中间它在页面被隐藏、进入往返缓存bfcache、或者被关闭时都会触发时机更早、覆盖面更全也是 web.dev 官方推荐用来做离开上报的事件。把上报绑在 pagehide 上等于在浏览器还愿意配合的时候就把数据交出去。二、sendBeacon 怎么写document.addEventListener(pagehide, function () { const payload JSON.stringify({ event: page_hide, path: location.pathname, ts: Date.now() }); if (navigator.sendBeacon) { navigator.sendBeacon(/logcount.html, new Blob([payload], { type: text/plain })); } else { // 老浏览器降级方案 new Image().src /logcount.gif?data encodeURIComponent(payload); } });几个要点绑pagehide而不是beforeunload——后者在现代浏览器里已经不可靠Chrome 117 起对它的弹窗都做了限制body 用 Blob 包一下Content-Type 设成 text/plain 可以避开 CORS 预检sendBeacon 只支持 POST不能自定义 Header鉴权 token 要拼在 URL 或 body 里单个 beacon 的 body 不要超过 64KB超过会被浏览器静默丢弃。这段代码里有几个选择需要解释一下。用 pagehide 而不是 unload是因为 unload 触发得太晚浏览器已经在回收资源用 new Image() 兜底而不是继续用 XHR是因为图片请求会被浏览器在卸载时尽量发完这是老时代的兼容手段。Blob 的 type 写成 text/plain 是一个取巧的办法这种简单内容类型不会触发跨域预检请求beacon 能直接发出去服务端再自己解析 body 里的 JSON。实际项目里不会每次都手写 Blob通常会封装一个统一的上报函数把 JSON 序列化、类型声明、降级逻辑都收进去业务侧只关心传什么事件。下面这个封装做了三件事先把数据序列化成 JSON 并用 Blob 声明类型优先走 sendBeacon不支持时退回 fetch 的 keepalive最后再退到图片像素。function reportBeacon(url, data) { const payload new Blob( [JSON.stringify(data)], { type: application/json } ); if (navigator.sendBeacon navigator.sendBeacon(url, payload)) { return; // 浏览器已接受后台发送 } if (window.fetch) { // 降级fetch 开启 keepalive允许页面卸载后继续发送 fetch(url, { method: POST, keepalive: true, body: payload }); return; } // 最后兜底图片像素不推荐作为主路径 new Image().src url ?d encodeURIComponent(JSON.stringify(data)); } document.addEventListener(pagehide, function () { reportBeacon(/logcount.html, { event: page_hide, path: location.pathname, ts: Date.now() }); });这里有两个细节容易踩。一是 Blob 的 type 要显式写成 application/json服务端才能按 JSON 解析如果留空或写成 text/plain后端的 JSON 中间件可能直接报错。二是 sendBeacon 的返回值只是「浏览器接不接受这个任务」true 不代表服务端收到了所以关键数据不要只靠它用户真正点按钮、下单这种动作发生时就该立刻发而不是攒到关闭时才交。二·补错误写法与正确写法对照把团队里常见的写法摆在一起对照问题会更直观。下面这张表左边是线上常见的错误写法右边是修正后的写法每一行都是真实排查时反复出现的坑。错误写法问题正确写法在 unload 里发 XHR页面已开始销毁请求被取消绑 pagehide用 sendBeaconfetch 不带 keepalive卸载时 fetch 同样被掐fetch 加 keepalive:true直接传字符串当 bodyContent-Type 不对后端解析失败用 Blob 声明 application/json只在 beforeunload 上报移动端常不触发数据大量丢失pagehide 为主beforeunload 兜底一次 beacon 塞整屏数据超过体积上限被静默丢弃拆包只发关键字段这张表可以直接贴进 code review 的 checklist。新人最容易犯的不是不知道 sendBeacon而是知道了却把它绑在 unload 上、或者忘了用 Blob 包 JSON结果数据照样丢还以为是 API 本身不可靠。如下图关闭页埋点的三段验收路径三、三段验收清单写完代码不算完按下面三张清单逐项打勾任何一段漏了都不能上线。三段的意思是客户端发出去不等于服务端收到服务端收到不等于数据真的进了分析库。很多团队只看 DevTools 里那条请求变绿就以为万事大吉结果过两天发现看板上根本没有对应事件——问题出在服务端解析失败或者入库管道断了而客户端那一端是绿的。所以三段必须分别验收任何一段漏了都不能上线。第一段客户端「真的发出去了」这一段的具体操作是这样的打开 Chrome DevTools 切到 Network 面板先勾选面板上方的 Preserve log保留日志——这一步最关键默认情况下页面一关闭请求列表会被清空你根本看不到关闭瞬间发出去的那条请求。接着正常操作页面再通过关标签页、点外链或点浏览器返回触发离开回到 Network 面板过滤你的打点域名。这时应该能看到一条 POST 请求发起类型Initiator里能看到 beacon 相关字样。点开这条请求确认 Status 是 200 或 (pending) 而不是 (canceled)再切到 Payload 标签核对 body 里的事件名、页面路径和时间戳是否完整。如果看到的是 (canceled)说明上报还在被浏览器取消多半是事件绑错了或者没用 sendBeacon。Chrome DevTools Network 过滤埋点域名关闭页面时能看到一条 POST 请求请求状态是 (pending) 或 200不是 (canceled)请求 body 完整没有被截断切换到移动端 Safari 复测一遍iOS 的限制和 Chrome 不同断网状态下关闭页面请求不应该阻塞 UI第二段服务端「真的收到了」服务端 access log 里能看到对应的 POST 请求记录请求到达时间和客户端关闭时间差在 1 秒内跨域 OPTIONS 预检没有被触发beacon 用 text/plain 本应免预检用 curl 模拟 beacon 请求服务端能正常解析 body第三段数据「真的落库了」后台事件列表里能查到这条 page_hide 事件把同一时间窗口的 page_view 和 page_hide 配对配对率应在 90% 以上停留时长分布不再集中在 1~2 秒这种异常区间观察 24 小时关闭事件量与 PV 比例稳定不突增突降如下图三段验收各自的检查项与通过标准四、beacon 也救不了的场景sendBeacon 不是万能的。下面这些情况它照样丢场景会丢吗对策用户正常关闭标签页基本不丢靠 pagehide beacon用户切换到后台一段时间可能丢visibilitychange 也打一次用户直接杀浏览器进程会丢关键事件在用户操作时立即发不要等关闭断网状态关闭会丢本地队列 下次启动补发请求 body 超过 64KB会被静默丢弃拆包或只发关键字段还有一个移动端特有的场景值得单独说。用户在手机上把浏览器切到后台、或者直接切到别的 App这时候页面并没有被关闭pagehide 不一定触发但人其实已经走了。这种情况下建议同时监听 visibilitychange当 document.visibilityState 变成 hidden 时再补一次离开上报。否则移动用户的停留时长会被算得偏长——系统以为他还在看其实早就切走了。把 pagehide 和 visibilitychange 两个事件都绑上同一份上报逻辑移动端的数据才不会虚高。落到具体的统计工具上主流 Web JS SDK 一般都把常规浏览和事件上报做了队列缓冲自定义事件通过全局队列 _yhxw456_trackdata.push([event, 分类, 名称, 属性]) 上报。开发者在卸载时刻补充的离开、停留时长事件可以在 SDK 常规上报之外再用上面这套 pagehide 加 sendBeacon 的逻辑兜底发一份两者配合关闭瞬间的流失才不会成为盲区。在工具侧事件分析与实时流量监控可看到 page_view 和 page_hide 的配对率要按「丢失率」这种维度做长期下钻需要按维度拆分事件这部分在专业版及以上更顺手。具体档位与配额以官网定价页为准。常见问题Q1为什么页面关闭时 XHR 埋点会丢A页面卸载时浏览器会取消未完成的请求XHR/fetch 在 beforeunload 里发出往往发不出去。这是浏览器行为不是网络问题。Q2sendBeacon 有什么限制A只支持 POSTbody 大小通常限制在 64KB 以内不能自定义请求头里的鉴权字段且是异步、不等响应的。Q3为什么不建议用 beforeunloadA现代浏览器已逐步弃用 beforeunload改用 pagehide。Chrome 从 117 起对 beforeunload 弹窗做了限制埋点也建议绑到 pagehide。Q4sendBeacon 一定能发出去吗A不能。它由浏览器保证在后台排队但如果用户直接杀进程或断网照样会丢。所以关键路径埋点不能只靠 beacon要在用户操作时就发。Q5怎么验收 beacon 真的到了服务端A三段验收DevTools Network 看到请求、服务端 access log 收到、数据库落库。只看客户端发出去不算数。总结关闭页埋点的核心不是「用什么 API」而是「怎么证明它真的到了」。把发送、到达、入库这三段验收清单贴进上线 Checklist每次接新埋点都过一遍停留时长这种敏感指标就不会再莫名短一截。绑事件选 pagehide 不选 unload发数据选 sendBeacon 不选裸 XHR调试时记得勾 Preserve log——这三件事做到位剩下的只是把它固化成团队规范。工具能帮你看数据看板但这三关必须自己盯发送、到达、入库任何一段断了看板上的漂亮数字都站不住。数据来源W3C Beacon API 规范MDN Web Docs《navigator.sendBeacon》MDN Web Docs《Page Visibility API》MDN Web Docs《beforeunload 事件》
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

2026 AI动作捕捉系统市场分析:无标记动捕技术如何推动体育训练与影视动画规模化落地? 2026/9/30 15:54:42

2026 AI动作捕捉系统市场分析:无标记动捕技术如何推动体育训练与影视动画规模化落地?

核心结论:全球AI动作捕捉系统市场正处于无标记技术替代传统光学方案的加速渗透期。无标记动捕依托计算机视觉算法与深度感应相机,在无需物理标记或传感器的条件下实现对目标运动的高精度跟踪与定位,这一技术特性正持续降低体育训练、康复训练…

阅读更多 →
一人公司如何选行业:从宏观分类到个人能力匹配的完整指南 2026/9/30 15:54:42

一人公司如何选行业:从宏观分类到个人能力匹配的完整指南

前几天有个朋友问我:“我一个人做点事,既不想回公司上班,也不想搞合伙,到底做什么行业比较好?”他把抖音上能刷到的赛道都列了一遍——自媒体、电商、做课、私域带货——看完更迷茫了,因为所有看起来热闹的…

阅读更多 →
【Python量化因子实战 #10】因子用了一个月失效了?用滚动 IC 监控稳定性 2026/9/30 15:54:42

【Python量化因子实战 #10】因子用了一个月失效了?用滚动 IC 监控稳定性

动量因子去年很灵,今年就不行了——这不是玄学,是量化里的常态。因子会衰减。本文教你用"滚动 IC"给因子做体检,判断它现在还能不能用。一、为什么因子会失效 A股的市场风格在切换: 2020-2021:抱团蓝筹&…

阅读更多 →
从告警扫描到攻击路径验证:为代码变更建立可审计的安全审查流水线 2026/9/30 15:54:42

从告警扫描到攻击路径验证:为代码变更建立可审计的安全审查流水线

在持续交付环境中,安全扫描很容易陷入两个极端:一端是只跑静态规则,输出大量告警,开发者只能靠经验逐条判断;另一端是把代码、日志和扫描结果直接交给模型,期望它给出“是否存在漏洞”的结论。前者缺少业务…

阅读更多 →
2026年企业级AI大模型API聚合平台终极测评:为什么不再自建网关 2026/9/30 15:54:19

2026年企业级AI大模型API聚合平台终极测评:为什么不再自建网关

2026年AI大模型加速企业数字化转型,基础设施层面的变革步入深水区:企业想同时用上GPT、Claude、Gemini、DeepSeek、Qwen、Llama等主流模型,还要保障网络连通性、统一结算与合规管控,难度不小,API聚合平台因此进入爆发期…

阅读更多 →
Linux目录结构深度解剖:从FHS标准到信创系统变异 2026/9/30 15:54:19

Linux目录结构深度解剖:从FHS标准到信创系统变异

1. 这不是命令手册,而是一张Linux系统的“活体解剖图”你打开终端敲下ls,看到的不只是文件列表;你输入cd /etc,踏进的也不是普通文件夹——那是Linux系统跳动的心脏腔室。我带过三十多个从Windows转过来的运维新人、开发实习生和信…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉