14

I've been going through the source to find out the critiera for jQuery.ajax()'s success/failure methods being called. It is not based solely on the status code, it seems to also involve the data type.

I always resort to writing custom error handlers using the 'complete'-callback.

Exactly which are the critera for the success/failure calls?

bjornl
  • 1,757
  • 3
  • 17
  • 29
  • Here is an example for creating custom errors: http://stackoverflow.com/questions/1637019/how-to-get-the-jquery-ajax-error-response-text – jantimon Oct 25 '10 at 09:33

2 Answers2

12

As you said, it depends on the data type, script is a special one for instance, the check is:

For other requests it's checks the following:

Note: The above is for jQuery 1.4.3, jQuery 1.4.2 and below had an additional "success" scenario where a response code of 0 was also "successful", this was done because Opera returns a 0 when it's really a 304. This is incorrect behavior, and the jQuery team opted to drop support for this quirk, since it caused false-positives in other actual 0 response code cases.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 1
    Thanks! Very comprehensive answer. Setting the dataType to 'text' should bypass parsing of the response (thus suppressing possible 'parseerror')? It still gives me parseerror, any idea what might be t he cause of this? – bjornl Oct 25 '10 at 11:37
  • 1
    @bjornl - It's checking the content type header and finding "json" most likely, it'll attempt to parse it if so. – Nick Craver Oct 25 '10 at 11:49
  • The Content-Type is set to 'application/octet-stream' - it's a REST protocol – bjornl Oct 25 '10 at 12:37
  • The header is created using Java's HttpServletResponse.setContentType() method – bjornl Oct 25 '10 at 12:38
0

I think you can see this in the jquery code in github line 394 and on:

http://github.com/jquery/jquery/blob/master/src/ajax.js

In depends on the readyState code you receive mainly and a variable where it controls the timeout:

var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
// The request was aborted
if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
// Opera doesn't call onreadystatechange before this point
// so we simulate the call
if ( !requestDone ) {
jQuery.handleComplete( s, xhr, status, data );
}

requestDone = true;
if ( xhr ) {
xhr.onreadystatechange = jQuery.noop;
}

// The transfer is complete and the data is available, or the request timed out
} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
requestDone = true;
xhr.onreadystatechange = jQuery.noop;

status = isTimeout === "timeout" ?
"timeout" :
!jQuery.httpSuccess( xhr ) ?
"error" :
s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
"notmodified" :
"success";

var errMsg;

if ( status === "success" ) {
// Watch for, and catch, XML document parse errors
try {
// process the data (runs the xml through httpData regardless of callback)
data = jQuery.httpData( xhr, s.dataType, s );
} catch( parserError ) {
status = "parsererror";
errMsg = parserError;
}
}

// Make sure that the request was successful or notmodified
if ( status === "success" || status === "notmodified" ) {
// JSONP handles its own success callback
if ( !jsonp ) {
jQuery.handleSuccess( s, xhr, status, data );
}
} else {
jQuery.handleError( s, xhr, status, errMsg );
}

// Fire the complete handlers
if ( !jsonp ) {
jQuery.handleComplete( s, xhr, status, data );
}

if ( isTimeout === "timeout" ) {
xhr.abort();
}

// Stop memory leaks
if ( s.async ) {
xhr = null;
}
}
};
netadictos
  • 7,602
  • 2
  • 42
  • 69