krafthaus/bauhaus

View on GitHub
bower_components/jquery/src/ajax/xhr.js

Summary

Maintainability
F
5 days
Test Coverage
define([
    "../core",
    "../var/support",
    "../ajax"
], function( jQuery, support ) {

// Create the request object
// (This is still attached to ajaxSettings for backward compatibility)
jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
    // Support: IE6+
    function() {

        // XHR cannot access local files, always use ActiveX for that case
        return !this.isLocal &&

            // Support: IE7-8
            // oldIE XHR does not support non-RFC2616 methods (#13240)
            // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
            // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
            // Although this check for six methods instead of eight
            // since IE also does not support "trace" and "connect"
            /^(get|post|head|put|delete|options)$/i.test( this.type ) &&

            createStandardXHR() || createActiveXHR();
    } :
    // For all other browsers, use the standard XMLHttpRequest object
    createStandardXHR;

var xhrId = 0,
    xhrCallbacks = {},
    xhrSupported = jQuery.ajaxSettings.xhr();

// Support: IE<10
// Open requests must be manually aborted on unload (#5280)
if ( window.ActiveXObject ) {
    jQuery( window ).on( "unload", function() {
        for ( var key in xhrCallbacks ) {
            xhrCallbacks[ key ]( undefined, true );
        }
    });
}

// Determine support properties
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
xhrSupported = support.ajax = !!xhrSupported;

// Create transport if the browser can provide an xhr
if ( xhrSupported ) {

    jQuery.ajaxTransport(function( options ) {
        // Cross domain only allowed if supported through XMLHttpRequest
        if ( !options.crossDomain || support.cors ) {

            var callback;

            return {
                send: function( headers, complete ) {
                    var i,
                        xhr = options.xhr(),
                        id = ++xhrId;

                    // 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 ];
                        }
                    }

                    // 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 ) {
                        // Support: IE<9
                        // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
                        // request header to a null-value.
                        //
                        // To keep consistent with other XHR implementations, cast the value
                        // to string and ignore `undefined`.
                        if ( headers[ i ] !== undefined ) {
                            xhr.setRequestHeader( i, headers[ i ] + "" );
                        }
                    }

                    // 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 );

                    // Listener
                    callback = function( _, isAbort ) {
                        var status, statusText, responses;

                        // Was never called and is aborted or complete
                        if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
                            // Clean up
                            delete xhrCallbacks[ id ];
                            callback = undefined;
                            xhr.onreadystatechange = jQuery.noop;

                            // Abort manually if needed
                            if ( isAbort ) {
                                if ( xhr.readyState !== 4 ) {
                                    xhr.abort();
                                }
                            } else {
                                responses = {};
                                status = xhr.status;

                                // Support: IE<10
                                // Accessing binary-data responseText throws an exception
                                // (#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 && options.isLocal && !options.crossDomain ) {
                                    status = responses.text ? 200 : 404;
                                // IE - #1450: sometimes returns 1223 when it should be 204
                                } else if ( status === 1223 ) {
                                    status = 204;
                                }
                            }
                        }

                        // Call complete if needed
                        if ( responses ) {
                            complete( status, statusText, responses, xhr.getAllResponseHeaders() );
                        }
                    };

                    if ( !options.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 {
                        // Add to the list of active xhr callbacks
                        xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
                    }
                },

                abort: function() {
                    if ( callback ) {
                        callback( undefined, true );
                    }
                }
            };
        }
    });
}

// Functions to create xhrs
function createStandardXHR() {
    try {
        return new window.XMLHttpRequest();
    } catch( e ) {}
}

function createActiveXHR() {
    try {
        return new window.ActiveXObject( "Microsoft.XMLHTTP" );
    } catch( e ) {}
}

});