@@ -25,7 +25,7 @@ support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
2525support . ajax = xhrSupported = ! ! xhrSupported ;
2626
2727jQuery . ajaxTransport ( function ( options ) {
28- var callback ;
28+ var callback , errorCallback ;
2929
3030 // Cross domain only allowed if supported through XMLHttpRequest
3131 if ( support . cors || xhrSupported && ! options . crossDomain ) {
@@ -72,17 +72,26 @@ jQuery.ajaxTransport( function( options ) {
7272 callback = function ( type ) {
7373 return function ( ) {
7474 if ( callback ) {
75- callback = xhr . onload = xhr . onerror = null ;
75+ callback = errorCallback = xhr . onload =
76+ xhr . onerror = xhr . onabort = xhr . onreadystatechange = null ;
7677
7778 if ( type === "abort" ) {
7879 xhr . abort ( ) ;
7980 } else if ( type === "error" ) {
80- complete (
8181
82- // File: protocol always yields status 0; see #8605, #14207
83- xhr . status ,
84- xhr . statusText
85- ) ;
82+ // Support: IE9
83+ // On a manual native abort, IE9 throws
84+ // errors on any property access that is not readyState
85+ if ( typeof xhr . status !== "number" ) {
86+ complete ( 0 , "error" ) ;
87+ } else {
88+ complete (
89+
90+ // File: protocol always yields status 0; see #8605, #14207
91+ xhr . status ,
92+ xhr . statusText
93+ ) ;
94+ }
8695 } else {
8796 complete (
8897 xhrSuccessStatus [ xhr . status ] || xhr . status ,
@@ -103,7 +112,31 @@ jQuery.ajaxTransport( function( options ) {
103112
104113 // Listen to events
105114 xhr . onload = callback ( ) ;
106- xhr . onerror = callback ( "error" ) ;
115+ errorCallback = xhr . onerror = callback ( "error" ) ;
116+
117+ // Support: IE9
118+ // Use onreadystatechange to replace onabort
119+ // to handle uncaught aborts
120+ if ( xhr . onabort !== undefined ) {
121+ xhr . onabort = errorCallback ;
122+ } else {
123+ xhr . onreadystatechange = function ( ) {
124+
125+ // Check readyState before timeout as it changes
126+ if ( xhr . readyState === 4 ) {
127+
128+ // Allow onerror to be called first,
129+ // but that will not handle a native abort
130+ // Also, save errorCallback to a variable
131+ // as xhr.onerror cannot be accessed
132+ window . setTimeout ( function ( ) {
133+ if ( callback ) {
134+ errorCallback ( ) ;
135+ }
136+ } ) ;
137+ }
138+ } ;
139+ }
107140
108141 // Create the abort callback
109142 callback = callback ( "abort" ) ;
0 commit comments