Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery AJAX fires error callback on window unload - how do I filter out unload and only catch real errors?

If I navigate away from a page in the middle of an $.ajax() request it fires the error callback. I've tested in Safari and FF with both GET and POST requests.

One potential solution would be to abort all AJAX requests on page unload, but the error handler is called before unload, so this doesn't seem possible.

I want to be able to handle REAL errors such as 500s gracefully on the client side with a polite alert or a modal dialog, but I don't want this handling to be called when a user navigates away from the page.

How do I do this?

--

(Also strange: When navigating away from a page, the error handler says that the textStatus parameter is "error", the same it throws when receiving a 500/bad request.)

like image 272
Graham Avatar asked Sep 02 '09 21:09

Graham


People also ask

How do you abort an AJAX call?

Just use ajax.abort(); } //then you make another ajax request $. ajax( //your code here );

Is there any way to wait for AJAX response and halt execution?

Solution 1: Making Synchronous AJAX CallsYou can write asynchronous AJAX calls so that it waits for the response before moving on to the next statements. If you are using jQuery, you can easily do this by setting the async option to false. However, if you are not using jQuery, like when you use $.

How does error handle response in AJAX?

When there is an AJAX error response or the AJAX request times out, you'll want to log as much information as you have, including the error message that jQuery gives you, the url and the request data. $. ajax(url, { "data": requestData, "type": "POST", "timeout": 5000 }) .

How do I cancel my ongoing AJAX request?

ajax({ type: 'POST', url: 'someurl', success: function(result){} }); Then you can abort the request: request. abort();


2 Answers

In the error callback or $.ajax you have three input arguments:

function (XMLHttpRequest, textStatus, errorThrown) {    this; // options for this ajax request } 

You can check directly the xhr.status to get the HTTP response code, for example:

$.ajax({   url: "test.html",   cache: false,   success: function(html){     $("#results").append(html);   },   error: function (xhr, textStatus) {     if (xhr.status == 500) {       alert('Server error: '+ textStatus);     }   } }); 

Edit: To tell the difference between a connection broken by the browser and the case where the server is down (jasonmerino's comment):

On unload the xhr.readyState should be 0, where for a non responsive server the xhr.readyState should be 4.

like image 133
Christian C. Salvadó Avatar answered Oct 04 '22 08:10

Christian C. Salvadó


This is a tough one to handle correctly in all situations. Unfortunately in many popular browsers the xhr.status is the same (0) if the AJAX call is cancelled by navigation or by a server being down / unresponsive. So that technique rarely works.

Here's a set of highly "practical" hacks that I've accumulated that work fairly well in the majority of circumstances, but still isn't bullet-proof. The idea is to try to catch the navigate events and set a flag which is checked in the AJAX error handler. Like this:

var global_is_navigating = false;  $(window).on('beforeunload',function() {     // Note: this event doesn't fire in mobile safari     global_is_navigating = true; });  $("a").on('click',function() {     // Giant hack that can be helpful with mobile safari     if( $(this).attr('href') ) {         global_is_navigating = true;     } });  $(document).ajaxError(function(evt, xhr, settings) {     // default AJAX error handler for page     if( global_is_navigating ) {         // AJAX call cancelled by navigation. Not a real error         return;     }     // process actual AJAX error here. }); 
like image 20
Leopd Avatar answered Oct 04 '22 10:10

Leopd