1

So basically I want to be able to tell the difference between when an ajax call failed naturally (eg 404, server down, etc etc) and when it has been canceled by the browser, eg when a user closes a tab or hits f5.

I listen for failed ajax attempts and display an error dialogue, describing the error when ajax fails. However when someone presses f5 (especially noticeable in firefox), the error callback of not yet complete ajax calls occur, then displays errors and while the page loads the user is stuck looking at the error dialogue until the whole page is torn down by the browser (which is not nice to look at, when in reality it doesn't matter that the ajax call failed because the whole web app is being reloaded).

I have examined the xmlHttp request object, and nothing stands out to me as a way to tell the two situations apart. I have also tried adding a delay, but this hasn't really worked so well either. So I am just wondering if it is possible, and if so how?

Josh Mc
  • 9,911
  • 8
  • 53
  • 66
  • So you're saying that if an Ajax call is in progress and the user tries to navigate away from the page that you actually get a client-side error on the Ajax connection? Can you make a jsFiddle that shows this so we can look at the situation ourselves? That seems a bit odd to me. I would think that the current page would just disappear (including the JS state) and a new page would be opened. – jfriend00 Apr 11 '14 at 05:05
  • Yes that is exactly what I am saying. Yes you would think that it would just tear down the JS state etc, but this is not how the browsers work, they seem to cancel all Ajax querys, and call the failure callbacks associated with them. I think the browser probably just waits for all synchronous activity to complete before actually cleaning up the JS State. It would be difficult to create a fiddle, as the problem is more shown by a) having a slow response from the index.htm server, and b) refreshing the browser manually. – Josh Mc Apr 11 '14 at 05:16
  • Woah, are you using synchronous Ajax? That's your problem. Stop using synchronous Ajax. I doubt you have this problem if you code for async Ajax. – jfriend00 Apr 11 '14 at 05:17
  • No no, I mean't the rest of synchronous javascript code (ie, all code except Timeouts, intervals, ajax and the like) – Josh Mc Apr 11 '14 at 05:18
  • Couldn't you just put a check in the error callback to see what type of error it was? i.e. if it is 404 or 500 display an error to the user otherwise, do nothing. – lampwins Apr 11 '14 at 05:27
  • In this jsFiddle demo, I do not get an error on an open ajax call when the user navigates away during the ajax call: http://jsfiddle.net/jfriend00/St4MU/ – jfriend00 Apr 11 '14 at 05:36
  • You're going to have to show us how to reproduce what you're seeing with code because I think there's something else going on here that you aren't disclosing. Vanilla async Ajax calls in progress do NOT give errors when the page is changed. – jfriend00 Apr 11 '14 at 05:56
  • Look at this question here for more information: http://stackoverflow.com/questions/20774198/what-is-the-ajax-response-when-closing-the-browser-in-the-middle-of-a-call . I tried your jsfiddle, and it did as you said, did not fire back a failure call, interestingly, if I changed the jquery version from v2 to v1, it did what I am talking about (http://jsfiddle.net/St4MU/19/) @jfriend00 I do appreciate the help on this strange issue. – Josh Mc Apr 11 '14 at 06:06
  • @lampwins, When I tested the jqxhr Object, it came back with many blank fields with status 0, I am willing to check for this if it is reliable, I guess I am not really aware of all the cases where this may happen, so I wasn't sure if I should feel confident relying on this. (I don't want to hide real legitimate errors). – Josh Mc Apr 11 '14 at 06:10

1 Answers1

2

I found a work-around. If you set a window.onbeforeunload handler, that will get called before the ajax error. So, if you set a flag that the document is unloading, you can check that flag before showing your ajax error and skip the error if the document is in the process of unloading.

Works for me with jQuery 1.11 in Firefox, Chrome and IE.

You can see it work here: http://jsfiddle.net/jfriend00/G3wat/

var unloading = false;
$(window).on("beforeunload", function() {
    unloading = true;
});

Then, in your ajax calls:

    error: function(jqXHR, status, err) {
        if (!unloading) {
            alert("Error status " + status);
        }

And, as you found, it appears that jQuery 2.x does this for you.

jfriend00
  • 683,504
  • 96
  • 985
  • 979