在返回AJAX响应之前阻止web浏览器关闭

Preventing web browser from closing until AJAX response is returned

本文关键字:web 浏览器 返回 AJAX 响应      更新时间:2023-09-26

我有一个在网络浏览器中运行的游戏(作为插件),我想做的是:

  1. 检测用户是否决定关闭浏览器(Alt+F4,点击"X"按钮等)

  2. 当我们向我们的网络服务发出呼叫以记录用户已关闭浏览器时,防止浏览器关闭

  3. 一旦我们收到来自web服务的响应,请释放锁定并允许浏览器按要求关闭。

我们想这样做的主要原因是我们遇到了一些并发问题,通过查看日志,我们想将注销/关闭浏览器的人与插件崩溃的真实实例隔离开来。

我考虑过用JQuery做这件事(为了X-Browser的兼容性-Opera不起作用,但谢天谢地,我们在Opera上没有任何用户):

$(window).bind('beforeunload', function(e) {
    e.preventDefault();
    // make AJAX call
});

问题是,这会向用户显示一个确认对话框("你确定要离开这个页面吗"),用户可能会在发送AJAX调用之前进行确认。

所以问题是,有没有一种方法可以防止浏览器在收到响应之前关闭?此外,当页面更改时,"beforeunload"也会触发——有没有办法区分点击链接和实际点击关闭?

感谢你对此事的帮助!

避免浏览器窗口关闭是一项棘手的业务。实际上,除了从onbeforeunload事件返回一个非undefined值之外,没有其他方法可以做到这一点,就像您所描述的那样。

我可以提出一个可能的建议,那就是在onbeforeunload事件中创建一个同步的ajax请求。例如

window.onbeforeunload = function() {
    $.ajax({
        url: '/foo',
        type: 'GET',
        async: false,
        timeout: 4000
    });
};

理论上,这将阻止浏览器最多4秒。事实上,浏览器会以不同的方式对待这一点。例如,Firefox(我在9上测试过它)确实不会立即关闭窗口,但它也不尊重那里的超时值。我想在请求被取消和窗口/选项卡关闭之前,内部最长时间为2秒。然而,我想在大多数情况下,这应该已经足够了。

你的另一个问题(如何区分点击链接)相当简单。如上所述,onbeforeunload查看从其事件处理程序返回的内容。因此,假设我们的应用程序有一个全局变量,我们可以做一些类似的事情

var globalIndicator = true;
// ... lots of code
window.onbeforeunload = function() {
    return globalIndicator;
};

此时,当窗口/选项卡即将关闭时,我们总是会收到一个确认对话框。如果我们想避免任何锚点点击,我们可以像一样进行修补

$( 'a[href^=http]' ).on('click', function() {
    globalIndicator = undefined;
});

关于问题的第一部分,除了使用window.onbeforeunload之外,没有可靠的方法可以阻止浏览器关闭。浏览器是为用户服务的,如果用户选择关闭浏览器,它就会这样做

对于您的第二个问题,通过jQuery:可以很容易地将点击链接与触发onbeforeunload事件的其他事件区分开来

$('a').click(function(e) {...});

例如,您可以使用它来确保点击不会触发unbeforeunload:

$('a').click(function(e) {window.onbeforeunload = null});

您可以使用以下代码来防止浏览器关闭:-

window.onbeforeunload = function() {
//Your code goes here.
    return "";
} 

现在,当用户关闭浏览器时,由于返回",他会收到确认对话框&等待用户的确认&这个等待时间使得请求到达服务器。

我确信使用JavaScript是不可能实现您想要的。但既然你有一个浏览器插件,难道你就不能检查你的插件对象是否被正确清理了吗?我不确定你是在使用ActiveX、NPAPI还是类似Firebreath的东西,但这些框架都有生命周期方法,在正常关闭的情况下,这些方法会在你的插件上被调用,所以你现在应该能够在日志中写一些东西。如果插件崩溃,将不会调用这些插件。