原因
过去,许多网站使用 unload 或 beforeunload 事件以在会话结束时发送统计数据。然而这是不可靠的,在许多情况下(尤其是移动设备)浏览器不会产生 unload、beforeunload 或 pagehide 事件。下面列出了一种不触发上述事件的情况:
用户加载了网页并与其交互。
完成浏览后,用户切换到了其他应用程序,而不是关闭选项卡。
随后,用户通过手机的应用管理器关闭了浏览器应用。
此外,unload 事件与现代浏览器实现的往返缓存(bfcache)不兼容。在部分浏览器(如:Firefox)通过在 bfcache 中排除包含 unload 事件处理器的页面来解决不兼容问题,但这存在性能损失。其他浏览器,例如 Safari 和 Android 上的 Chrome 浏览器则采取用户在同一标签页下导航至其他页面时不触发 unload 事件的方法来解决不兼容问题。
官方详细说明:https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/sendBeacon
解决办法
1.可靠的方法是在 visibilitychange 事件发生时使用 navigator.sendBeacon发送数据,
document.addEventListener("visibilitychange", function logData() {if (document.visibilityState === "hidden") {navigator.sendBeacon("/log", analyticsData);}
});
2.使用 pagehide 事件来代替部分浏览器未实现的 visibilitychange 事件。和 beforeunload 与 unload 事件类似,这一事件不会被可靠地触发(特别是在移动设备上),但它与 bfcache 兼容。