关闭浏览器/标签页时调用.NET MVC Action,onbeforeunload确认后请求失效如何解决
你遇到的问题核心是preventNavigation函数直接对window.onbeforeunload赋值,覆盖了之前绑定的包含sendBeacon逻辑的事件处理函数,所以当表单存在未保存修改时,触发的beforeunload事件里没有发送请求的逻辑,自然不会调用Controller方法。
最佳实践是拆分两个逻辑的绑定时机:
- 把清理Session的请求放到
unload事件中触发:unload事件仅在页面确认要被卸载时执行,不会因为用户取消离开弹窗而误触发,避免Session被误删。 - 用
addEventListener绑定事件,代替直接赋值window.onbeforeunload,避免事件逻辑被覆盖。
完整实现代码
// 页面确认卸载时发送清理Session请求 window.addEventListener('unload', function () { navigator.sendBeacon("/ABC/RemoveSession"); }); // 标记是否有未保存的修改 let hasUnsavedChanges = false; // 监听表单输入变化,更新标记 $("#myform :input").change(function () { hasUnsavedChanges = true; }); // 表单保存成功后调用,重置标记 function onFormSaved() { hasUnsavedChanges = false; } // 绑定离开确认逻辑 window.addEventListener('beforeunload', function (e) { // 没有未保存修改直接返回 if (!hasUnsavedChanges) return; e = e || window.event; const tip = "您有未保存的修改,离开页面将会丢失所有未保存内容"; if (e) e.returnValue = tip; // 注意:现代浏览器大多会忽略自定义提示文本,仅显示系统默认的离开确认文案 return tip; });
注意事项
- 不要在
unload事件中执行同步AJAX、复杂计算等阻塞操作,仅用navigator.sendBeacon发送异步请求即可,浏览器会保证该请求在页面卸载前完成发送。 - 如果需要兼容不支持
sendBeacon的极旧浏览器,可以降级为async: false的AJAX请求,但会阻塞页面卸载,影响用户体验,非必要不建议使用。
内容的提问来源于stack exchange,提问作者Mako
相关产品推荐
相关产品推荐

