11

So supposedly starting at Firefox > 4, binding the window jQuery object to beforeunload doesn't work anymore.

What'd I'd like to do is submit an AJAX post to delete my server's memcache data.

When I refresh the only open tab, I can see that the beforeunload event is called in both firefox and chrome with the following code as evidenced by the console.log message, "firefox/NON-firefox delete". The problem is that I never see the console.log message "memcache delete" indicating that my server never saw the $.ajax request.

I realize it is bad to do browser sniffing and that there is no difference between what's included in the if and else statements. I'm merely showing code for what I've tried unsuccessfully in Firefox.

Anyone have any ideas?

$(window).bind('beforeunload', function(){ 
  if(/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) {
    console.log('firefox delete');
     memcacheDelete();
     return null;
  } 
  else {
    console.log('NON-firefox delete');
    memcacheDelete();
    return null;
  }
});

function memcacheDelete() {
   $.ajax({
      url: "/memcache/delete", 
      type: "post",
      data:{}, 
      success:function(){
          console.log('memcache deleted');
      }//success
  }); //ajax
}
Community
  • 1
  • 1
tim peterson
  • 23,653
  • 59
  • 177
  • 299

2 Answers2

11

Ajax is asynchronous.

When you refresh (or close)your browser, beforeunload is being called. And it means as soon as beforeunload is finished executing, page will refresh (or close).

When you do an ajax request, (since its asynchronous) javascript interpreter does not wait for ajax success event to be executed and moves down finishing the execution of beforeunload.

success of ajax is supposed to be called after few secs, but you dont see it as page has been refreshed / closed.

Side note:

.success() method is deprecated and is replaced by the .done() method

Reference

Jashwant
  • 28,410
  • 16
  • 70
  • 105
  • yes...the way i understand asynch calls this is what i thought...+1 – cliffbarnes Feb 18 '13 at 05:27
  • 2
    @Jashwant, thanks for the explanation.Though, I have evidence that the memcache delete succeeded when using Chrome after closing/re-opening the browser, but it is still **not** deleting with firefox. There seems to be something else going on here..would converting the `$.ajax` to synchronous, `async:false`, help? – tim peterson Feb 18 '13 at 05:33
  • 4
    It looks like changing [the `$.ajax` option `async` to `false`](http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings) corrects the problem. Is there any reason one wouldn't want to do that? – tim peterson Feb 18 '13 at 05:41
  • Usually ajax is `true`, as we dont want to wait until ajax completion. If you'll set `async` to `false` , your javascript code after ajax call wont execute until server's response. In your case specifically, I think refreshing / closing may take few seconds (until ajax is complete) – Jashwant Feb 18 '13 at 05:45
  • @jashwant, +1 for the comment about `done()` replacing `success()`. I didn't know that. It would seem that waiting in my case is ok as I'm storing state data in memcache and don't want to confuse the user by showing "old" data if the memcache doesn't delete (and subsequently get refreshed upon the reload). So better to wait than show bad data, don't you think? – tim peterson Feb 18 '13 at 05:50
  • 1
    Yes. all options for developer's sake . Use the one that suits you :) – Jashwant Feb 18 '13 at 05:51
  • deos it works for chrome and safari? – java seeker Mar 23 '14 at 14:53
  • It should. Test yourself and do let the community know :) – Jashwant Mar 23 '14 at 18:04
8

Just for sake of completion, here's what I did, thanks to @Jashwant for the guidance: I noticed that this other SO Q&A suggested the same solution. The KEY is the async:true(false) in the $.ajax call below:

$(window).bind('beforeunload', function(){ 
  if(/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) {
    console.log('firefox delete');
     var data={async:false};
     memcacheDelete(data);
     return null;
  } 
  else {
    console.log('NON-firefox delete');
     var data={async:true};
     memcacheDelete(data);
    return null;
  }
});

function memcacheDelete(data) {
  $.ajax({
    url: "/memcache/delete", 
    type: "post",
    data:{}, 
    async:data.async,
    success:function(){
      console.log('memcache deleted');
    }//success
  }); //ajax
}
Community
  • 1
  • 1
tim peterson
  • 23,653
  • 59
  • 177
  • 299
  • 1
    Just to feed my curiosity. What is the meaning (use) of `&& new Number(RegExp.$1) >= 4` in your Firefox-detecting routine (if)? Just assuring, that Firefox is in version 4 or newer? – trejder Jul 02 '13 at 11:24