views:

87

answers:

2

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?

+2  A: 

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
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
@bjornl - It's checking the content type header and finding "json" most likely, it'll attempt to parse it if so.
Nick Craver
The Content-Type is set to 'application/octet-stream' - it's a REST protocol
bjornl
The header is created using Java's HttpServletResponse.setContentType() method
bjornl
A: 

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