35

Is there a way to handle the error from an ajax request within JQuery such that when the user navigates away from the page, the resulting error is ignored?

$(document).ready(function() {
 $.ajax( {
    url:'/server/url/',
    type: 'POST',
    data: {some..data},
    success:function(response) { do stuff with response },
    error: function(xhr, textStatus, errorThrown) {
           // Don't raise this alert if user has navigated away from the page
           alert('error');
    }
});

I'm curious if anybody knows of a clean way to handle this? I know you could create some logic in a $(window).bind("beforeunload", function(){}) method but I'd prefer if there was a way to handle the situation without doing this since Chrome appears to no longer support it. Is there for example a specific error that is returned in this case?

Thanks.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Steve Walsh
  • 6,363
  • 12
  • 42
  • 54
  • Since the call is to the server, I don't think it would have enough knowledge to return a response differently depending on whether the user navigated off that page or not. Is there somewhere you can provide an example of this behavior? It seems odd that a script from another page would continue running after you'd navigated off that page. – Will Buck Feb 10 '12 at 14:09
  • I *think* the script actually stops running and an error is thrown since it is terminated prematurely. – Steve Walsh Feb 10 '12 at 14:21
  • Once you navigate away, your AJAX call goes in the bit-bucket. There is no longer a listener on the client to receive any message from that request. – Diodeus - James MacFarlane Feb 10 '12 at 14:23
  • 1
    The error callback is being invoked. But, the xhr.status is 0 which presumably could be used to filter this condition. – Steve Walsh Feb 10 '12 at 15:18
  • 1
    possible duplicate of [jQuery AJAX fires error callback on window unload?](http://stackoverflow.com/questions/1370322/jquery-ajax-fires-error-callback-on-window-unload) – Leopd Jun 04 '12 at 15:11
  • https://bugzilla.mozilla.org/show_bug.cgi?id=768596 – 4esn0k Aug 20 '13 at 08:07

3 Answers3

19

It looks like the answer to this is to examine the jqXHR.status. The XMLHttpRequest spec outlines these steps to set the status:

The status attribute must return the result of running these steps:

  1. If the state is UNSENT or OPENED, return 0 and terminate these steps.

  2. If the error flag is set, return 0 and terminate these steps.

  3. Return the HTTP status code.1

NOTE also: The error flag indicates some type of network error or request abortion. It is initially unset and is used during the DONE state.

From what I understand therefore, this code check should fix the issue:

    if (xhr.status == 0)
        alert('error');

1https://web.archive.org/web/20120204040047/http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
Steve Walsh
  • 6,363
  • 12
  • 42
  • 54
  • Precisely the answer I was looking for. Binding new events is over-engineering. – eighteyes Mar 29 '13 at 20:03
  • 5
    Is there a way to differentiate between the case when someone navigates away from the page and other network issues (timeout, host not found, etc)? – Krystian Cybulski May 20 '13 at 21:51
  • 1
    [This](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests) article says that _by the time the response comes back, the page has unloaded and the callback function won’t exist anymore_, so how does the error callback even reliably work? – winterlight Aug 28 '13 at 11:03
  • 1
    Shouldn't that be `xhr.status == 0` instead? – user2141650 Sep 17 '13 at 19:00
  • error: function(xhr, textStatus, errorThrown) { if (xhr.readyState === 4) alert(error); } – nicoabie Jul 29 '14 at 18:36
  • Does not work for me. For me in both cases (navigating away from the page as well as network error) the jqXHR status is 0 and readyState is 0 too. – Benedikt Nov 27 '20 at 07:47
14

Checking the status didn't work for me, but

// Ignore incomplete requests, likely due to navigating away from the page
if (jqXHR.readyState < 4) {
    return true;
} 

in the error handler did (4 being DONE).

Kevin Gorski
  • 3,745
  • 1
  • 22
  • 16
  • If the server process exists, the jqXHR.readyState value will be 0. This should in fact go to the error handling as it is not the case that the user is navigating away. – Lorenz03Tx Oct 06 '14 at 20:37
  • I cannot agree. I am using current FireFox and jQuery v2.0.0. When I follow a link during an ajax request, then the ajax request ends in jqXHR.readyState = 4 and jqXHR.status = 404. – Simon Oct 04 '16 at 13:02
3

I've had to handle this issue too a couple of times.

I'd recommend binding to the $(window).unload event, setting some variable somewhere, such as in your namespace (App.unloading = true) and then testing it in ajax error callbacks.

See http://api.jquery.com/unload/

ori
  • 7,817
  • 1
  • 27
  • 31
  • This seems to not work for all browsers:http://code.google.com/p/chromium/issues/detail?id=4422 – Steve Walsh Feb 10 '12 at 15:12
  • 2
    See http://stackoverflow.com/questions/1370322/jquery-ajax-fires-error-callback-on-window-unload for alternative approaches. Maybe combining unload event & flag with status checking could prove to be enough. – ori Feb 10 '12 at 15:23