你以为 beforeunload 够用了?今天 Chrome 悄悄把 unload 事件的开关彻底关了

你以为 beforeunload 够用了?今天 Chrome 悄悄把 unload 事件的开关彻底关了

如果你在页面离开时还靠 unload 事件做数据上报、session 记录或者性能监控,这条消息需要认真看一下:Chrome/Edge 152 正式对 unload 事件引入了 Permission-Policy 控制,从这个版本开始,浏览器会默认拦截它。


发生了什么

Chrome/Edge 152(2026 年 8 月 27 日稳定版)引入了 Unload Permission-Policy,默认值在 152-155 期间分阶段从 allow 迁移到 deny

具体节奏是这样的:

  • Edge 152:60% 的页面加载默认不再触发 unload 处理器
  • Edge 154:这一比例升至 80%
  • Edge 155:默认彻底关闭,除非站点主动声明 Permissions-Policy: allow=unload

这意味着,如果你的监控 SDK、埋点脚本、session 回放工具还在 unload 事件里打点,6 个月后这些数据会开始大面积断崖式丢失——而且用户那边完全无感。


为什么之前不修

unload 事件名声一直不好,MDN 多年前就打上了”不可靠”的标签,但它为什么还是被广泛使用?

因为它看起来能用。在 Chrome 真正实施拦截之前,大多数桌面浏览器的 unload 在正常页面导航场景下确实会触发——只是当用户关闭标签、关闭浏览器、或者页面进入 bfcache(往返缓存)时,它根本不 fire。

bfcache 把整个页面快照保存在内存里,下次前进后退时直接恢复,不走任何卸载流程。这在现代浏览器里是默认行为,意味着用户点了浏览器后退键,你的 unload 可能一次都不触发。

所以真正可靠的两个替代品早就存在了:

  • beforeunload:用户真的要跳走之前触发,浏览器会询问用户”是否离开”
  • pagehide:bfcache 入场前触发,是 MPA 单页应用推荐的替代方案

谁会被打疼

第一类:Session 回放和录像工具

FullStory、Hotjar 这类靠记录用户操作轨迹的产品,如果底层还绑在 unload 上,在 bfcache 场景下最后一屏交互会直接丢失。大多数主流工具已经在迁移到 visibilitychange + pagehide,但中小厂商和自研方案不一定跟上了。

第二类:前端性能监控

以前有人会在 unload 里打最后一个 Performance Entry,或者记录 FCP / LCP 的最终时间戳。这在 unload 被拦截之后,这个数据点会持续缺失,导致长会话的性能分析出现空白区间。

第三类:单页应用的路由离开守卫

有些 MPA 架构在用户点导航链接时靠 unload 触发确认逻辑。在 SPA 里这个场景已经被 beforeunload 处理了,但如果你的项目两套混用,unload 被禁会暴露这个设计债务。


你现在能做什么

立即可做:检查依赖 unload 的代码

// 快速扫描
window.addEventListener("unload", () => {
  // 你的上报逻辑在这里?
  sendAnalytics();
});

如果搜到了,下一步是把这条逻辑迁移到 pagehide

window.addEventListener("pagehide", (event) => {
  if (event.persisted) {
    // 进入了 bfcache,资源会被释放,不需要再上报
    return;
  }
  // 真正的卸载
  sendAnalytics();
});

对于真正需要弹窗确认的场景,beforeunload 仍然保留:

window.addEventListener("beforeunload", (event) => {
  event.preventDefault();
  // 现代浏览器需要在这里手动返回字符串才能触发确认框
  event.returnValue = "";
});

CI/CD 相关:如果你是提供监控 SDK 的人

你需要在 SDK 初始化时主动声明 Permission-Policy,告诉浏览器”我需要 unload”:

Permissions-Policy: allow="unload"

放在 HTTP 响应头里,或者在 HTML 的 <iframe> 层面用 allow="unload" 属性。这个声明是你主动申请的,不会随浏览器默认策略收紧而失效。


写在最后

浏览器封掉 unload 的逻辑很清晰:它是历史遗留的不可靠行为,容易被滥用做跨页面追踪,在隐私优先的年代继续保留它代价大于收益。

这个变化提醒了一件事:前端工程师习惯把”能用”当成”正确”,但浏览器的底线一直在收紧。beforeunload 明年会不会也被降权?pagehidepersisted 属性在 Safari 里表现不一致的问题会不会被修复?这些都值得在架构评审时放进来一起看。

趁现在还有 6 个月的窗口期,把这条埋在 unload 里的技术债清掉,比到时候被用户行为数据断崖追着跑要体面得多。

评论区

0 条评论

登录后可评论。