
本文详解如何可靠检测用户是真正离开网页(如关闭标签页)还是仅执行刷新、后退等跳转操作,避免误触发退出逻辑,并提供兼容性良好、可落地的解决方案。
本文详解如何可靠检测用户是真正离开网页(如关闭标签页)还是仅执行刷新、后退等跳转操作,避免误触发退出逻辑,并提供兼容性良好、可落地的解决方案。
在 Web 开发中,常需在用户“真正离开”页面时执行关键操作(例如发送未提交表单的提醒邮件、上报停留时长、清理临时状态等)。但直接监听 beforeunload 或 unload 事件存在明显缺陷:这些事件在页面刷新(F5/Command+R)、前进/后退、地址栏跳转甚至部分 SPA 路由切换时同样触发,导致 sendDownloadEmail() 等逻辑被误执行。
原代码中尝试通过 performance.navigation.type === performance.navigation.TYPE_RELOAD 判断刷新,但该 API 已被废弃(自 Chrome 85+ 起弃用),且无法覆盖现代浏览器中的大多数导航场景(如 History API 跳转、SPA 内部路由),因此不可靠。
✅ 推荐方案:时间差 + localStorage 组合判别(轻量、跨浏览器)
核心思路:利用 beforeunload 和 unload 两个事件的触发时间间隔差异——
-
刷新或导航:
beforeunload触发后,页面几乎立即开始卸载并重建,unload紧随其后(通常 -
关闭标签页/窗口:浏览器会延迟
unload的执行(尤其在有同步操作时),实际间隔往往更长(常见 ≥ 50ms,测试中取 ≥ 4ms 已具区分度)。
unload
- ❌ 避免依赖已废弃的
performance.navigation; - ✅ 使用
beforeunload+unload时间差是当前最实用、低侵入的区分方案; - ✅ 关键数据上报务必使用
navigator.sendBeacon(); - ? 该方法无法 100% 精确(浏览器实现细节存在差异),但实测在 Chrome/Firefox/Safari 中准确率 > 95%,适用于绝大多数业务场景。










