Preventing web browser from closing until AJAX response is returned [duplicate]

痞子三分冷 提交于 2020-01-09 19:13:11

问题


I've got a game that runs in the web browser (as a plugin) and what I'm trying to do is:

  1. Detect if the user has decided to close the browser (Alt+F4, hitting the 'X' button etc)

  2. Prevent the browser from closing whilst we fire a call to our web services to log that the user has closed the browser

  3. Once we receive the response from the web services, release the lock and allow the browser to close as requested.

The main reason we want to do this is we're having some concurrency problems and going through our logs we want to isolate people logging out / closing the browser from genuine instances where the plugin has crashed.

I looked into doing this with JQuery (for X-Browser compatability - Opera won't work but we don't have any users on Opera anyway thankfully):

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

The problem is that this displays a confirmation dialog to the user ('Are you sure you want to leave this page') which the user might confirm before the AJAX call is sent.

So the question is, is there a way of preventing the browser from closing until the response is received? Also 'beforeunload' fires when the page is changed as well - is there a way of distinguishing clicking on a link from actually clicking close?

Grateful for any help wrt to this!


回答1:


Its tricky business to avoid the browser window from beeing closed. Actually, there is no way to do that, beside returning a non-undefined value from the onbeforeunload event, like you described.

There is one possible suggestion I can make, that is creating a synchronized ajax request within the onbeforeunload event. For instance

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

In theory, this will block the browser for a maximum of 4 seconds. In reality, browsers will treat this differently. For instance, Firefox (I tested it on 9), will indeed not close the window immediately, but it also does not respect the timeout value there. I guess there is an internal maximum of like 2 seconds before the request is canceled and the window/tab gets closed. However, that should be enough in most cases I guess.

Your other question (how to distinguish between clicking a link), is fairly simple. As described above, onbeforeunload looks what is getting returned from its event handlers. So lets assume we have a variable which is global for our application, we could do something like

var globalIndicator = true;

// ... lots of code

window.onbeforeunload = function() {
    return globalIndicator;
};

At this point, we would always receive a confirmation dialog when the window/tab is about to get closed. If we want to avoid that for any anchor-click, we could patch it like

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



回答2:


As for the first part of your question, there is no reliable way of preventing the browser from closing other than using window.onbeforeunload. The browser is there to serve the user and if the user chooses to close his browser then it will do so.

For your second question, it is reasonably easy to distinguish a click on a link from other events triggering an onbeforeunload event by jQuery:

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

You could use this, for example, to make sure a click will not trigger unbeforeunload:

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



回答3:


You can use below code to prevent the browser from getting closed:-

window.onbeforeunload = function() {

//Your code goes here.

    return "";
} 

Now when user closes the browser then he gets the confirmation dialogue because of return ""; & waits for user's confirmation & this waiting time makes the request to reach the server.




回答4:


I'm pretty sure that what you want isn't possible using JavaScript. But since you have a browser plugin, shouldn't you be able to check whether your plugin object was cleaned up correctly? I'm not sure if you're using ActiveX, NPAPI or something like Firebreath, but these frameworks all have lifecycle methods that will be called on your plugin in the event of a normal shutdown, so you should be able to write something to the logs at this point. If the plugin crashes, these won't be called.



来源:https://stackoverflow.com/questions/8743119/preventing-web-browser-from-closing-until-ajax-response-is-returned

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!