Prevent closing a web browser before returning an AJAX response

I have a game that works in a web browser (as a plugin) and I'm trying to do this:

  • Determine if the user has decided to close the browser (Alt + F4 by pressing the "X" button, etc.)

  • Prevent closing the browser while we launch a call to our web services to register that the user has closed the browser

  • As soon as we get a response from the web services, release the lock and let the browser close the request.

The main reason that we want to do this is because we have problems with concurrency and through our logs we want to isolate users from entering / closing the browser from real instances where the plug-in crashed.

I learned this with jQuery (for compatibility with the X browser - Opera will not work, but we don’t have anyone in Opera anyway):

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

The problem is that it displays a confirmation dialog to the user (“You really want to leave this page”), which the user can confirm before sending an AJAX call.

So the question is, is there a way to prevent the browser from closing before receiving an answer? In addition, "beforeunload" is triggered when the page also changes - is there a way to differ by clicking on the link from the actual closing click?

Thanks for any help on this!

+7
source share
4 answers

Its a difficult business to avoid closing the browser window. In fact, there is no way to do this other than returning an undefined value from the onbeforeunload event, as you described.

There is one possible suggestion that I can make is to create a synchronized ajax request in the onbeforeunload event. For example,

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

In theory, this blocks the browser for a maximum of 4 seconds. In fact, browsers will treat this differently. For example, Firefox (I checked it for 9) doesn’t really close the window right away, but it also doesn’t respect the timeout value. I assume that there is an internal maximum, like 2 seconds before the request is canceled, and the window / tab closes. However, in most cases this should be enough.

Your other question (how to distinguish a click on a link) is quite simple. As described above, onbeforeunload looks to be returned from event handlers. So let's assume that we have a global variable for our application, we could do something like

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

At this point, we will always receive a confirmation dialog when the window / tab is closed. If we want to avoid this for any click of the anchor, we can fix it as

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

Regarding the first part of your question, there is no reliable way to prevent the browser from closing, other than using window.onbeforeunload . The browser must serve the user, and if the user wants to close his browser, he will do so.

For your second question, it’s easy enough to distinguish a click on a link from other events that trigger the onbeforeunload event on jQuery:

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

You can use this, for example, to make sure that a click does not cause unbeforeunload :

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

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

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

Now, when the user closes the browser, he receives a confirmation dialog due to the return of ""; and waits for user confirmation, and this timeout makes the request available to the server.

+1
source

I am sure you cannot use JavaScript. But since you have a browser plugin, can't you check if your plugin object was cleaned correctly? I'm not sure if you use ActiveX, NPAPI or something like Firebreath, but these frameworks have lifecycle methods that will be called in your plugin in case of normal shutdown, so you should be able to write something in the logs in this moment. If the plugin fails, they will not be called.

0
source

All Articles