Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Ajax: trigger error callback on native abort
- IE9 does not have onabort. Use onreadystatechange instead.
Fixes gh-2079
Close gh-2684
- Loading branch information
Showing
with
61 additions
and
9 deletions.
-
+41
−8
src/ajax/xhr.js
-
+20
−1
test/unit/ajax.js
|
|
@@ -25,7 +25,7 @@ support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); |
|
|
support.ajax = xhrSupported = !!xhrSupported; |
|
|
|
|
|
jQuery.ajaxTransport( function( options ) { |
|
|
var callback; |
|
|
var callback, errorCallback; |
|
|
|
|
|
// Cross domain only allowed if supported through XMLHttpRequest |
|
|
if ( support.cors || xhrSupported && !options.crossDomain ) { |
|
|
@@ -72,17 +72,26 @@ jQuery.ajaxTransport( function( options ) { |
|
|
callback = function( type ) { |
|
|
return function() { |
|
|
if ( callback ) { |
|
|
callback = xhr.onload = xhr.onerror = null; |
|
|
callback = errorCallback = xhr.onload = |
|
|
xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; |
|
|
|
|
|
if ( type === "abort" ) { |
|
|
xhr.abort(); |
|
|
} else if ( type === "error" ) { |
|
|
complete( |
|
|
|
|
|
// File: protocol always yields status 0; see #8605, #14207 |
|
|
xhr.status, |
|
|
xhr.statusText |
|
|
); |
|
|
// Support: IE9 |
|
|
// On a manual native abort, IE9 throws |
|
|
// errors on any property access that is not readyState |
|
|
if ( typeof xhr.status !== "number" ) { |
|
|
complete( 0, "error" ); |
|
|
} else { |
|
|
complete( |
|
|
|
|
|
// File: protocol always yields status 0; see #8605, #14207 |
|
|
xhr.status, |
|
|
xhr.statusText |
|
|
); |
|
|
} |
|
|
} else { |
|
|
complete( |
|
|
xhrSuccessStatus[ xhr.status ] || xhr.status, |
|
|
@@ -103,7 +112,31 @@ jQuery.ajaxTransport( function( options ) { |
|
|
|
|
|
// Listen to events |
|
|
xhr.onload = callback(); |
|
|
xhr.onerror = callback( "error" ); |
|
|
errorCallback = xhr.onerror = callback( "error" ); |
|
|
|
|
|
// Support: IE9 |
|
|
// Use onreadystatechange to replace onabort |
|
|
// to handle uncaught aborts |
|
|
if ( xhr.onabort !== undefined ) { |
|
|
xhr.onabort = errorCallback; |
|
|
} else { |
|
|
xhr.onreadystatechange = function() { |
|
|
|
|
|
// Check readyState before timeout as it changes |
|
|
if ( xhr.readyState === 4 ) { |
|
|
|
|
|
// Allow onerror to be called first, |
|
|
// but that will not handle a native abort |
|
|
// Also, save errorCallback to a variable |
|
|
// as xhr.onerror cannot be accessed |
|
|
window.setTimeout( function() { |
|
|
if ( callback ) { |
|
|
errorCallback(); |
|
|
} |
|
|
} ); |
|
|
} |
|
|
}; |
|
|
} |
|
|
|
|
|
// Create the abort callback |
|
|
callback = callback( "abort" ); |
|
|
|
|
|
@@ -38,7 +38,7 @@ QUnit.module( "ajax", { |
|
|
); |
|
|
|
|
|
ajaxTest( "jQuery.ajax() - success callbacks", 8, function( assert ) { |
|
|
return { |
|
|
return { |
|
|
setup: addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxSuccess", assert ), |
|
|
url: url( "data/name.html" ), |
|
|
beforeSend: function() { |
|
|
@@ -437,6 +437,25 @@ QUnit.module( "ajax", { |
|
|
}; |
|
|
} ); |
|
|
|
|
|
ajaxTest( "jQuery.ajax() - native abort", 2, function( assert ) { |
|
|
return { |
|
|
url: url( "data/name.php?wait=1" ), |
|
|
xhr: function() { |
|
|
var xhr = new window.XMLHttpRequest(); |
|
|
setTimeout( function() { |
|
|
xhr.abort(); |
|
|
}, 100 ); |
|
|
return xhr; |
|
|
}, |
|
|
error: function( xhr, msg ) { |
|
|
assert.strictEqual( msg, "error", "Native abort triggers error callback" ); |
|
|
}, |
|
|
complete: function() { |
|
|
assert.ok( true, "complete" ); |
|
|
} |
|
|
}; |
|
|
} ); |
|
|
|
|
|
ajaxTest( "jQuery.ajax() - events with context", 12, function( assert ) { |
|
|
var context = document.createElement( "div" ); |
|
|
|
|
|
|