如何在选项卡/浏览器关闭时调用 .NET MVC 操作?

Posted

技术标签:

【中文标题】如何在选项卡/浏览器关闭时调用 .NET MVC 操作?【英文标题】:How can I call a .NET MVC action on tab/browser close? 【发布时间】:2021-11-18 21:55:46 【问题描述】:

作为我的 MVC Web 应用程序的一部分,我需要在浏览器或浏览器选项卡关闭时调用控制器方法。我正在使用 javascript onbeforeunload 事件来调用该方法。

 window.onbeforeunload = function () 
            navigator.sendBeacon("/ABC/RemoveSession");
        

如果在表单中进行了一些更改并且用户尝试退出,我将使用以下代码显示一个确认窗口

        function preventNavigation(message) 
            var confirmOnPageExit = function (e) 
                // If we haven't been passed the event get the window.event
                e = e || window.event;
                // For IE6-8 and Firefox prior to version 4
                if (e) 
                    e.returnValue = message;
                
                // For Chrome, Safari, IE8+ and Opera 12+
                return message;
            ;

            window.onbeforeunload = confirmOnPageExit
        

$("#myform :input").change(function () 

       preventNavigation("You have not saved the form. Any changes will be lost if you leave this page.");
           
        );

如果表单没有变化,并且标签页关闭,代码工作正常,Controller方法调用成功。但是,如果表单已更改,用户会在尝试关闭表单时弹出确认消息。单击“离开”按钮时,选项卡会关闭,但不会调用控制器方法。

我怀疑这是否可以通过 onbeforeunload 事件完成。如果有人遇到过这样的问题或知道任何更好的方法来实现这一点,请告诉我。

【问题讨论】:

能否通过发送 POST 请求触发相同的事件? @LajosArpad XHR POST 请求与 Beacon 请求不同,不能保证完成发送 @ErmiyaEskandary 我的问题背后的原因是我们需要知道问题是 unbeforeunload 没有完成,还是问题可能出在请求本身。因此,测试发送 POST 请求并查看它是否始终如一地工作是有意义的。如果是这样,那么需要一个解决方案来解决在卸载前发送的请求的不可靠性。如果不是,则需要先修复请求,然后才能评估 unbeforeunload 的问题。因此,我们的想法是分别测试可能出现的问题,并在解决之前查看问题到底是什么。 【参考方案1】:

onbeforeunload 似乎是确定用户是否完成页面的非常不可靠的事件。 MSDN 甚至对此提出警告,并建议在文档(而不是您用于 onbeforeunload 的窗口对象)上发生 visibilitychange 事件。

根据 MSDN 与页面的任何交互都可以阻止它触发。请尝试:

document.addEventListener('visibilitychange', function logData() 
  if (document.visibilityState === 'hidden') 
    navigator.sendBeacon('/ABC/RemoveSession');
  
);

【讨论】:

【参考方案2】:

Navigator.sendBeacon() 用于visibilitychange 事件, onbeforeunload

MDN states:

避免卸载和卸载前

过去,许多网站使用 unload 或 beforeunload 事件在会话结束时发送分析。但是,这是非常不可靠在许多情况下,尤其是在移动设备上,浏览器不会触发 unload、beforeunload 或 pagehide 事件。例如,这些事件不会在以下情况下触发:

    用户加载页面并与之交互。 完成后,他们会切换到其他应用,而不是关闭选项卡。 随后,他们使用手机的应用管理器关闭了浏览器应用。

...

替换:

window.onbeforeunload = function() 
    navigator.sendBeacon("/ABC/RemoveSession");

与:

document.addEventListener('visibilitychange', function() 
  if (document.visibilityState === 'hidden') 
    navigator.sendBeacon("/ABC/RemoveSession");
  
);

【讨论】:

以上是关于如何在选项卡/浏览器关闭时调用 .NET MVC 操作?的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET MVC 的控制器中打开新选项卡中的链接

导航到新选项卡时调用异步函数

如何关闭 ASP.NET 应用程序的默认选项卡

如何在 Angular 中处理浏览器选项卡关闭事件?只关闭不刷新

关闭浏览器或选项卡时如何获取 Web 通知

如何在javascript中检测浏览器选项卡是不是关闭或浏览器窗口