Preventing web browser from closing until AJAX response is returned

11,840

Solution 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;
});

Solution 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});

Solution 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.

Share:
11,840
csdev86
Author by

csdev86

Updated on June 05, 2022

Comments

  • csdev86
    csdev86 almost 2 years

    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!

  • csdev86
    csdev86 over 12 years
    Thanks Andreas for your input; so there's actually no way of preventing the browser from closing until a response is received... the problem is if the player is on a slow connection; 2 secs might not be long enough to make the call. Thanks for the explanation for distinguishing between clicking a link - most helpful
  • csdev86
    csdev86 over 12 years
    The fact we couldn't make the call from the plugin reliably was the reason why started to look at doing it from the web browser.
  • smorgan
    smorgan over 12 years
    If you think about how it could be used, it's pretty clear that no browser would allow a page to block for an arbitrarily long time before closing. If it were possible, someone could, e.g., make a popup ad that a user could never close.