Chrome页面卸载前执行函数的跨浏览器兼容实现方案咨询
问题原因
Chrome 89及以上版本已经正式禁用了beforeunload、unload等页面卸载相关事件中的同步XHR请求,你原来使用async: false的jQuery ajax方案自然会失效,Firefox目前仍保留兼容但后续也会逐步禁用,该方案本身已不符合最新浏览器规范。
跨浏览器兼容解决方案
推荐使用W3C专门为页面卸载场景设计的navigator.sendBeacon() API,浏览器会保证在后台异步完成请求发送,不会阻塞页面卸载流程,兼容Chrome、Firefox、Safari、Edge等几乎所有主流现代浏览器,再搭配降级方案覆盖极端老浏览器即可:
$(window).on("beforeunload", function() { // 构造请求参数 const formData = new FormData(); formData.append('userid', 34); // 优先使用标准sendBeacon方案 if (navigator.sendBeacon) { navigator.sendBeacon('logout.php', formData); return; } // 降级方案1:fetch + keepalive属性 try { fetch('logout.php', { method: 'POST', body: formData, keepalive: true, credentials: 'include' // 按需添加,需要携带Cookie时开启 }); return; } catch (e) {} // 最终兜底:仅极端老旧浏览器才会走到这步,使用同步XHR const xhr = new XMLHttpRequest(); xhr.open('POST', 'logout.php', false); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('userid=34'); });
注意事项
sendBeacon默认仅支持POST请求,如果必须使用GET请求,可将参数拼接在URL后,调用navigator.sendBeacon('logout.php?userid=34')即可- 不要在
beforeunload事件中添加过多复杂逻辑,浏览器可能会中断执行耗时过长的任务 - 极端场景下(比如浏览器进程被强制杀死、设备断电)
beforeunload事件不会触发,核心的状态清理逻辑建议后端额外加超时兜底,不要完全依赖前端请求触发
内容的提问来源于stack exchange,提问作者Cain Nuke
相关产品推荐
相关产品推荐

