aboutsummaryrefslogtreecommitdiffstats
path: root/src/ajax/xhr.js
diff options
context:
space:
mode:
authorjaubourg <j@ubourg.net>2013-01-02 22:55:41 +0100
committerDave Methvin <dave.methvin@gmail.com>2013-01-07 10:34:07 -0500
commit17049c73bc5bf1a41cce4a5b648f55da7bbac533 (patch)
tree78d1b52390e02969cb46403e106df078904f80f0 /src/ajax/xhr.js
parentc61150427fc8ccc8e884df8f221a6c9bb5477929 (diff)
downloadjquery-17049c73bc5bf1a41cce4a5b648f55da7bbac533.tar.gz
jquery-17049c73bc5bf1a41cce4a5b648f55da7bbac533.zip
2.0: reduced xhr transport
Diffstat (limited to 'src/ajax/xhr.js')
-rw-r--r--src/ajax/xhr.js294
1 files changed, 84 insertions, 210 deletions
diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js
index 3c1fde374..9569c7064 100644
--- a/src/ajax/xhr.js
+++ b/src/ajax/xhr.js
@@ -1,218 +1,92 @@
-var xhrCallbacks, xhrSupported,
- xhrId = 0,
- // #5280: Internet Explorer will keep connections alive if we don't abort on unload
- xhrOnUnloadAbort = window.ActiveXObject && function() {
- // Abort all pending requests
- var key;
- for ( key in xhrCallbacks ) {
- xhrCallbacks[ key ]( undefined, true );
- }
- };
-
-// Functions to create xhrs
-function createStandardXHR() {
+jQuery.ajaxSettings.xhr = function() {
try {
- return new window.XMLHttpRequest();
+ return new XMLHttpRequest();
} catch( e ) {}
-}
-
-function createActiveXHR() {
- try {
- return new window.ActiveXObject("Microsoft.XMLHTTP");
- } catch( e ) {}
-}
-
-// Create the request object
-// (This is still attached to ajaxSettings for backward compatibility)
-jQuery.ajaxSettings.xhr = window.ActiveXObject ?
- /* Microsoft failed to properly
- * implement the XMLHttpRequest in IE7 (can't request local files),
- * so we use the ActiveXObject when it is available
- * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
- * we need a fallback.
- */
- function() {
- return !this.isLocal && createStandardXHR() || createActiveXHR();
- } :
- // For all other browsers, use the standard XMLHttpRequest object
- createStandardXHR;
-
-// Determine support properties
-xhrSupported = jQuery.ajaxSettings.xhr();
+};
+
+var xhrSupported = jQuery.ajaxSettings.xhr(),
+ xhrSuccessStatus = {
+ // file protocol always yields status code 0, assume 200
+ 0: 200,
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ 1223: 204
+ };
+
jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-xhrSupported = jQuery.support.ajax = !!xhrSupported;
-
-// Create transport if the browser can provide an xhr
-if ( xhrSupported ) {
-
- jQuery.ajaxTransport(function( s ) {
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( !s.crossDomain || jQuery.support.cors ) {
-
- var callback;
-
- return {
- send: function( headers, complete ) {
-
- // Get a new xhr
- var handle, i,
- xhr = s.xhr();
-
- // Open the socket
- // Passing null username, generates a login popup on Opera (#2865)
- if ( s.username ) {
- xhr.open( s.type, s.url, s.async, s.username, s.password );
- } else {
- xhr.open( s.type, s.url, s.async );
- }
-
- // Apply custom fields if provided
- if ( s.xhrFields ) {
- for ( i in s.xhrFields ) {
- xhr[ i ] = s.xhrFields[ i ];
- }
- }
-
- // Override mime type if needed
- if ( s.mimeType && xhr.overrideMimeType ) {
- xhr.overrideMimeType( s.mimeType );
+jQuery.support.ajax = xhrSupported = !!xhrSupported;
+
+jQuery.ajaxTransport(function( options ) {
+ var callback;
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
+ return {
+ send: function( headers, complete ) {
+ var i,
+ xhr = options.xhr();
+ // Open the socket
+ xhr.open( options.type, options.url, options.async, options.username, options.password );
+ // Apply custom fields if provided
+ if ( options.xhrFields ) {
+ for ( i in options.xhrFields ) {
+ xhr[ i ] = options.xhrFields[ i ];
}
-
- // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if ( !s.crossDomain && !headers["X-Requested-With"] ) {
- headers["X-Requested-With"] = "XMLHttpRequest";
- }
-
- // Need an extra try/catch for cross domain requests in Firefox 3
- try {
- for ( i in headers ) {
- xhr.setRequestHeader( i, headers[ i ] );
- }
- } catch( err ) {}
-
- // Do send the request
- // This may raise an exception which is actually
- // handled in jQuery.ajax (so no try/catch here)
- xhr.send( ( s.hasContent && s.data ) || null );
-
- // Listener
- callback = function( _, isAbort ) {
-
- var status,
- statusText,
- responseHeaders,
- responses,
- xml;
-
- // Firefox throws exceptions when accessing properties
- // of an xhr when a network error occurred
- // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
- try {
-
- // Was never called and is aborted or complete
- if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
-
- // Only called once
- callback = undefined;
-
- // Do not keep as active anymore
- if ( handle ) {
- xhr.onreadystatechange = jQuery.noop;
- if ( xhrOnUnloadAbort ) {
- delete xhrCallbacks[ handle ];
- }
- }
-
- // If it's an abort
- if ( isAbort ) {
- // Abort it manually if needed
- if ( xhr.readyState !== 4 ) {
- xhr.abort();
- }
- } else {
- responses = {};
- status = xhr.status;
- xml = xhr.responseXML;
- responseHeaders = xhr.getAllResponseHeaders();
-
- // Construct response list
- if ( xml && xml.documentElement /* #4958 */ ) {
- responses.xml = xml;
- }
-
- // When requesting binary data, IE6-9 will throw an exception
- // on any attempt to access responseText (#11426)
- if ( typeof xhr.responseText === "string" ) {
- responses.text = xhr.responseText;
- }
-
- // Firefox throws an exception when accessing
- // statusText for faulty cross-domain requests
- try {
- statusText = xhr.statusText;
- } catch( e ) {
- // We normalize with Webkit giving an empty statusText
- statusText = "";
- }
-
- // Filter status for non standard behaviors
-
- // If the request is local and we have data: assume a success
- // (success with no data won't get notified, that's the best we
- // can do given current implementations)
- if ( !status && s.isLocal && !s.crossDomain ) {
- status = responses.text ? 200 : 404;
- // IE - #1450: sometimes returns 1223 when it should be 204
- } else if ( status === 1223 ) {
- status = 204;
- }
- }
- }
- } catch( firefoxAccessException ) {
- if ( !isAbort ) {
- complete( -1, firefoxAccessException );
+ }
+ // Override mime type if needed
+ if ( options.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( options.mimeType );
+ }
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !options.crossDomain && !headers["X-Requested-With"] ) {
+ headers["X-Requested-With"] = "XMLHttpRequest";
+ }
+ // Set headers
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ // Callback
+ callback = function( type ) {
+ return function() {
+ if ( callback ) {
+ callback = xhr.onload = xhr.onerror = null;
+ if ( type === "abort" ) {
+ xhr.abort();
+ } else if ( type === "error" ) {
+ complete( xhr.status, xhr.statusText );
+ } else {
+ complete(
+ xhrSuccessStatus[ xhr.status ] || xhr.status,
+ xhr.statusText,
+ // IE - #11426: When requesting binary data, IE9 will
+ // throw an exception on any attempt to access responseText
+ typeof xhr.responseText === "string" ? {
+ text: xhr.responseText
+ } : undefined,
+ xhr.getAllResponseHeaders()
+ );
}
}
-
- // Call complete if needed
- if ( responses ) {
- complete( status, statusText, responses, responseHeaders );
- }
};
-
- if ( !s.async ) {
- // if we're in sync mode we fire the callback
- callback();
- } else if ( xhr.readyState === 4 ) {
- // (IE6 & IE7) if it's in cache and has been
- // retrieved directly we need to fire the callback
- setTimeout( callback );
- } else {
- handle = ++xhrId;
- if ( xhrOnUnloadAbort ) {
- // Create the active xhrs callbacks list if needed
- // and attach the unload handler
- if ( !xhrCallbacks ) {
- xhrCallbacks = {};
- jQuery( window ).unload( xhrOnUnloadAbort );
- }
- // Add to list of active xhrs callbacks
- xhrCallbacks[ handle ] = callback;
- }
- xhr.onreadystatechange = callback;
- }
- },
-
- abort: function() {
- if ( callback ) {
- callback( undefined, true );
- }
+ };
+ // Listen to events
+ xhr.onload = callback();
+ xhr.onerror = callback("error");
+ // Create the abort callback
+ callback = callback("abort");
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( options.hasContent && options.data || null );
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback();
}
- };
- }
- });
-}
+ }
+ };
+ }
+});