tuiHoneyPot

front and back end of my TUI honeypot
Log | Files | Refs | README

ajax.js (22924B)


      1 define( [
      2 	"./core",
      3 	"./var/document",
      4 	"./var/isFunction",
      5 	"./var/rnothtmlwhite",
      6 	"./ajax/var/location",
      7 	"./ajax/var/nonce",
      8 	"./ajax/var/rquery",
      9 
     10 	"./core/init",
     11 	"./core/parseXML",
     12 	"./event/trigger",
     13 	"./deferred",
     14 	"./serialize" // jQuery.param
     15 ], function( jQuery, document, isFunction, rnothtmlwhite, location, nonce, rquery ) {
     16 
     17 "use strict";
     18 
     19 var
     20 	r20 = /%20/g,
     21 	rhash = /#.*$/,
     22 	rantiCache = /([?&])_=[^&]*/,
     23 	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
     24 
     25 	// trac-7653, trac-8125, trac-8152: local protocol detection
     26 	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
     27 	rnoContent = /^(?:GET|HEAD)$/,
     28 	rprotocol = /^\/\//,
     29 
     30 	/* Prefilters
     31 	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
     32 	 * 2) These are called:
     33 	 *    - BEFORE asking for a transport
     34 	 *    - AFTER param serialization (s.data is a string if s.processData is true)
     35 	 * 3) key is the dataType
     36 	 * 4) the catchall symbol "*" can be used
     37 	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
     38 	 */
     39 	prefilters = {},
     40 
     41 	/* Transports bindings
     42 	 * 1) key is the dataType
     43 	 * 2) the catchall symbol "*" can be used
     44 	 * 3) selection will start with transport dataType and THEN go to "*" if needed
     45 	 */
     46 	transports = {},
     47 
     48 	// Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
     49 	allTypes = "*/".concat( "*" ),
     50 
     51 	// Anchor tag for parsing the document origin
     52 	originAnchor = document.createElement( "a" );
     53 
     54 originAnchor.href = location.href;
     55 
     56 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
     57 function addToPrefiltersOrTransports( structure ) {
     58 
     59 	// dataTypeExpression is optional and defaults to "*"
     60 	return function( dataTypeExpression, func ) {
     61 
     62 		if ( typeof dataTypeExpression !== "string" ) {
     63 			func = dataTypeExpression;
     64 			dataTypeExpression = "*";
     65 		}
     66 
     67 		var dataType,
     68 			i = 0,
     69 			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
     70 
     71 		if ( isFunction( func ) ) {
     72 
     73 			// For each dataType in the dataTypeExpression
     74 			while ( ( dataType = dataTypes[ i++ ] ) ) {
     75 
     76 				// Prepend if requested
     77 				if ( dataType[ 0 ] === "+" ) {
     78 					dataType = dataType.slice( 1 ) || "*";
     79 					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
     80 
     81 				// Otherwise append
     82 				} else {
     83 					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
     84 				}
     85 			}
     86 		}
     87 	};
     88 }
     89 
     90 // Base inspection function for prefilters and transports
     91 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
     92 
     93 	var inspected = {},
     94 		seekingTransport = ( structure === transports );
     95 
     96 	function inspect( dataType ) {
     97 		var selected;
     98 		inspected[ dataType ] = true;
     99 		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
    100 			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
    101 			if ( typeof dataTypeOrTransport === "string" &&
    102 				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
    103 
    104 				options.dataTypes.unshift( dataTypeOrTransport );
    105 				inspect( dataTypeOrTransport );
    106 				return false;
    107 			} else if ( seekingTransport ) {
    108 				return !( selected = dataTypeOrTransport );
    109 			}
    110 		} );
    111 		return selected;
    112 	}
    113 
    114 	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
    115 }
    116 
    117 // A special extend for ajax options
    118 // that takes "flat" options (not to be deep extended)
    119 // Fixes trac-9887
    120 function ajaxExtend( target, src ) {
    121 	var key, deep,
    122 		flatOptions = jQuery.ajaxSettings.flatOptions || {};
    123 
    124 	for ( key in src ) {
    125 		if ( src[ key ] !== undefined ) {
    126 			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
    127 		}
    128 	}
    129 	if ( deep ) {
    130 		jQuery.extend( true, target, deep );
    131 	}
    132 
    133 	return target;
    134 }
    135 
    136 /* Handles responses to an ajax request:
    137  * - finds the right dataType (mediates between content-type and expected dataType)
    138  * - returns the corresponding response
    139  */
    140 function ajaxHandleResponses( s, jqXHR, responses ) {
    141 
    142 	var ct, type, finalDataType, firstDataType,
    143 		contents = s.contents,
    144 		dataTypes = s.dataTypes;
    145 
    146 	// Remove auto dataType and get content-type in the process
    147 	while ( dataTypes[ 0 ] === "*" ) {
    148 		dataTypes.shift();
    149 		if ( ct === undefined ) {
    150 			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
    151 		}
    152 	}
    153 
    154 	// Check if we're dealing with a known content-type
    155 	if ( ct ) {
    156 		for ( type in contents ) {
    157 			if ( contents[ type ] && contents[ type ].test( ct ) ) {
    158 				dataTypes.unshift( type );
    159 				break;
    160 			}
    161 		}
    162 	}
    163 
    164 	// Check to see if we have a response for the expected dataType
    165 	if ( dataTypes[ 0 ] in responses ) {
    166 		finalDataType = dataTypes[ 0 ];
    167 	} else {
    168 
    169 		// Try convertible dataTypes
    170 		for ( type in responses ) {
    171 			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
    172 				finalDataType = type;
    173 				break;
    174 			}
    175 			if ( !firstDataType ) {
    176 				firstDataType = type;
    177 			}
    178 		}
    179 
    180 		// Or just use first one
    181 		finalDataType = finalDataType || firstDataType;
    182 	}
    183 
    184 	// If we found a dataType
    185 	// We add the dataType to the list if needed
    186 	// and return the corresponding response
    187 	if ( finalDataType ) {
    188 		if ( finalDataType !== dataTypes[ 0 ] ) {
    189 			dataTypes.unshift( finalDataType );
    190 		}
    191 		return responses[ finalDataType ];
    192 	}
    193 }
    194 
    195 /* Chain conversions given the request and the original response
    196  * Also sets the responseXXX fields on the jqXHR instance
    197  */
    198 function ajaxConvert( s, response, jqXHR, isSuccess ) {
    199 	var conv2, current, conv, tmp, prev,
    200 		converters = {},
    201 
    202 		// Work with a copy of dataTypes in case we need to modify it for conversion
    203 		dataTypes = s.dataTypes.slice();
    204 
    205 	// Create converters map with lowercased keys
    206 	if ( dataTypes[ 1 ] ) {
    207 		for ( conv in s.converters ) {
    208 			converters[ conv.toLowerCase() ] = s.converters[ conv ];
    209 		}
    210 	}
    211 
    212 	current = dataTypes.shift();
    213 
    214 	// Convert to each sequential dataType
    215 	while ( current ) {
    216 
    217 		if ( s.responseFields[ current ] ) {
    218 			jqXHR[ s.responseFields[ current ] ] = response;
    219 		}
    220 
    221 		// Apply the dataFilter if provided
    222 		if ( !prev && isSuccess && s.dataFilter ) {
    223 			response = s.dataFilter( response, s.dataType );
    224 		}
    225 
    226 		prev = current;
    227 		current = dataTypes.shift();
    228 
    229 		if ( current ) {
    230 
    231 			// There's only work to do if current dataType is non-auto
    232 			if ( current === "*" ) {
    233 
    234 				current = prev;
    235 
    236 			// Convert response if prev dataType is non-auto and differs from current
    237 			} else if ( prev !== "*" && prev !== current ) {
    238 
    239 				// Seek a direct converter
    240 				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
    241 
    242 				// If none found, seek a pair
    243 				if ( !conv ) {
    244 					for ( conv2 in converters ) {
    245 
    246 						// If conv2 outputs current
    247 						tmp = conv2.split( " " );
    248 						if ( tmp[ 1 ] === current ) {
    249 
    250 							// If prev can be converted to accepted input
    251 							conv = converters[ prev + " " + tmp[ 0 ] ] ||
    252 								converters[ "* " + tmp[ 0 ] ];
    253 							if ( conv ) {
    254 
    255 								// Condense equivalence converters
    256 								if ( conv === true ) {
    257 									conv = converters[ conv2 ];
    258 
    259 								// Otherwise, insert the intermediate dataType
    260 								} else if ( converters[ conv2 ] !== true ) {
    261 									current = tmp[ 0 ];
    262 									dataTypes.unshift( tmp[ 1 ] );
    263 								}
    264 								break;
    265 							}
    266 						}
    267 					}
    268 				}
    269 
    270 				// Apply converter (if not an equivalence)
    271 				if ( conv !== true ) {
    272 
    273 					// Unless errors are allowed to bubble, catch and return them
    274 					if ( conv && s.throws ) {
    275 						response = conv( response );
    276 					} else {
    277 						try {
    278 							response = conv( response );
    279 						} catch ( e ) {
    280 							return {
    281 								state: "parsererror",
    282 								error: conv ? e : "No conversion from " + prev + " to " + current
    283 							};
    284 						}
    285 					}
    286 				}
    287 			}
    288 		}
    289 	}
    290 
    291 	return { state: "success", data: response };
    292 }
    293 
    294 jQuery.extend( {
    295 
    296 	// Counter for holding the number of active queries
    297 	active: 0,
    298 
    299 	// Last-Modified header cache for next request
    300 	lastModified: {},
    301 	etag: {},
    302 
    303 	ajaxSettings: {
    304 		url: location.href,
    305 		type: "GET",
    306 		isLocal: rlocalProtocol.test( location.protocol ),
    307 		global: true,
    308 		processData: true,
    309 		async: true,
    310 		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
    311 
    312 		/*
    313 		timeout: 0,
    314 		data: null,
    315 		dataType: null,
    316 		username: null,
    317 		password: null,
    318 		cache: null,
    319 		throws: false,
    320 		traditional: false,
    321 		headers: {},
    322 		*/
    323 
    324 		accepts: {
    325 			"*": allTypes,
    326 			text: "text/plain",
    327 			html: "text/html",
    328 			xml: "application/xml, text/xml",
    329 			json: "application/json, text/javascript"
    330 		},
    331 
    332 		contents: {
    333 			xml: /\bxml\b/,
    334 			html: /\bhtml/,
    335 			json: /\bjson\b/
    336 		},
    337 
    338 		responseFields: {
    339 			xml: "responseXML",
    340 			text: "responseText",
    341 			json: "responseJSON"
    342 		},
    343 
    344 		// Data converters
    345 		// Keys separate source (or catchall "*") and destination types with a single space
    346 		converters: {
    347 
    348 			// Convert anything to text
    349 			"* text": String,
    350 
    351 			// Text to html (true = no transformation)
    352 			"text html": true,
    353 
    354 			// Evaluate text as a json expression
    355 			"text json": JSON.parse,
    356 
    357 			// Parse text as xml
    358 			"text xml": jQuery.parseXML
    359 		},
    360 
    361 		// For options that shouldn't be deep extended:
    362 		// you can add your own custom options here if
    363 		// and when you create one that shouldn't be
    364 		// deep extended (see ajaxExtend)
    365 		flatOptions: {
    366 			url: true,
    367 			context: true
    368 		}
    369 	},
    370 
    371 	// Creates a full fledged settings object into target
    372 	// with both ajaxSettings and settings fields.
    373 	// If target is omitted, writes into ajaxSettings.
    374 	ajaxSetup: function( target, settings ) {
    375 		return settings ?
    376 
    377 			// Building a settings object
    378 			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
    379 
    380 			// Extending ajaxSettings
    381 			ajaxExtend( jQuery.ajaxSettings, target );
    382 	},
    383 
    384 	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
    385 	ajaxTransport: addToPrefiltersOrTransports( transports ),
    386 
    387 	// Main method
    388 	ajax: function( url, options ) {
    389 
    390 		// If url is an object, simulate pre-1.5 signature
    391 		if ( typeof url === "object" ) {
    392 			options = url;
    393 			url = undefined;
    394 		}
    395 
    396 		// Force options to be an object
    397 		options = options || {};
    398 
    399 		var transport,
    400 
    401 			// URL without anti-cache param
    402 			cacheURL,
    403 
    404 			// Response headers
    405 			responseHeadersString,
    406 			responseHeaders,
    407 
    408 			// timeout handle
    409 			timeoutTimer,
    410 
    411 			// Url cleanup var
    412 			urlAnchor,
    413 
    414 			// Request state (becomes false upon send and true upon completion)
    415 			completed,
    416 
    417 			// To know if global events are to be dispatched
    418 			fireGlobals,
    419 
    420 			// Loop variable
    421 			i,
    422 
    423 			// uncached part of the url
    424 			uncached,
    425 
    426 			// Create the final options object
    427 			s = jQuery.ajaxSetup( {}, options ),
    428 
    429 			// Callbacks context
    430 			callbackContext = s.context || s,
    431 
    432 			// Context for global events is callbackContext if it is a DOM node or jQuery collection
    433 			globalEventContext = s.context &&
    434 				( callbackContext.nodeType || callbackContext.jquery ) ?
    435 				jQuery( callbackContext ) :
    436 				jQuery.event,
    437 
    438 			// Deferreds
    439 			deferred = jQuery.Deferred(),
    440 			completeDeferred = jQuery.Callbacks( "once memory" ),
    441 
    442 			// Status-dependent callbacks
    443 			statusCode = s.statusCode || {},
    444 
    445 			// Headers (they are sent all at once)
    446 			requestHeaders = {},
    447 			requestHeadersNames = {},
    448 
    449 			// Default abort message
    450 			strAbort = "canceled",
    451 
    452 			// Fake xhr
    453 			jqXHR = {
    454 				readyState: 0,
    455 
    456 				// Builds headers hashtable if needed
    457 				getResponseHeader: function( key ) {
    458 					var match;
    459 					if ( completed ) {
    460 						if ( !responseHeaders ) {
    461 							responseHeaders = {};
    462 							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
    463 								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
    464 									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
    465 										.concat( match[ 2 ] );
    466 							}
    467 						}
    468 						match = responseHeaders[ key.toLowerCase() + " " ];
    469 					}
    470 					return match == null ? null : match.join( ", " );
    471 				},
    472 
    473 				// Raw string
    474 				getAllResponseHeaders: function() {
    475 					return completed ? responseHeadersString : null;
    476 				},
    477 
    478 				// Caches the header
    479 				setRequestHeader: function( name, value ) {
    480 					if ( completed == null ) {
    481 						name = requestHeadersNames[ name.toLowerCase() ] =
    482 							requestHeadersNames[ name.toLowerCase() ] || name;
    483 						requestHeaders[ name ] = value;
    484 					}
    485 					return this;
    486 				},
    487 
    488 				// Overrides response content-type header
    489 				overrideMimeType: function( type ) {
    490 					if ( completed == null ) {
    491 						s.mimeType = type;
    492 					}
    493 					return this;
    494 				},
    495 
    496 				// Status-dependent callbacks
    497 				statusCode: function( map ) {
    498 					var code;
    499 					if ( map ) {
    500 						if ( completed ) {
    501 
    502 							// Execute the appropriate callbacks
    503 							jqXHR.always( map[ jqXHR.status ] );
    504 						} else {
    505 
    506 							// Lazy-add the new callbacks in a way that preserves old ones
    507 							for ( code in map ) {
    508 								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
    509 							}
    510 						}
    511 					}
    512 					return this;
    513 				},
    514 
    515 				// Cancel the request
    516 				abort: function( statusText ) {
    517 					var finalText = statusText || strAbort;
    518 					if ( transport ) {
    519 						transport.abort( finalText );
    520 					}
    521 					done( 0, finalText );
    522 					return this;
    523 				}
    524 			};
    525 
    526 		// Attach deferreds
    527 		deferred.promise( jqXHR );
    528 
    529 		// Add protocol if not provided (prefilters might expect it)
    530 		// Handle falsy url in the settings object (trac-10093: consistency with old signature)
    531 		// We also use the url parameter if available
    532 		s.url = ( ( url || s.url || location.href ) + "" )
    533 			.replace( rprotocol, location.protocol + "//" );
    534 
    535 		// Alias method option to type as per ticket trac-12004
    536 		s.type = options.method || options.type || s.method || s.type;
    537 
    538 		// Extract dataTypes list
    539 		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
    540 
    541 		// A cross-domain request is in order when the origin doesn't match the current origin.
    542 		if ( s.crossDomain == null ) {
    543 			urlAnchor = document.createElement( "a" );
    544 
    545 			// Support: IE <=8 - 11, Edge 12 - 15
    546 			// IE throws exception on accessing the href property if url is malformed,
    547 			// e.g. http://example.com:80x/
    548 			try {
    549 				urlAnchor.href = s.url;
    550 
    551 				// Support: IE <=8 - 11 only
    552 				// Anchor's host property isn't correctly set when s.url is relative
    553 				urlAnchor.href = urlAnchor.href;
    554 				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
    555 					urlAnchor.protocol + "//" + urlAnchor.host;
    556 			} catch ( e ) {
    557 
    558 				// If there is an error parsing the URL, assume it is crossDomain,
    559 				// it can be rejected by the transport if it is invalid
    560 				s.crossDomain = true;
    561 			}
    562 		}
    563 
    564 		// Convert data if not already a string
    565 		if ( s.data && s.processData && typeof s.data !== "string" ) {
    566 			s.data = jQuery.param( s.data, s.traditional );
    567 		}
    568 
    569 		// Apply prefilters
    570 		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
    571 
    572 		// If request was aborted inside a prefilter, stop there
    573 		if ( completed ) {
    574 			return jqXHR;
    575 		}
    576 
    577 		// We can fire global events as of now if asked to
    578 		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
    579 		fireGlobals = jQuery.event && s.global;
    580 
    581 		// Watch for a new set of requests
    582 		if ( fireGlobals && jQuery.active++ === 0 ) {
    583 			jQuery.event.trigger( "ajaxStart" );
    584 		}
    585 
    586 		// Uppercase the type
    587 		s.type = s.type.toUpperCase();
    588 
    589 		// Determine if request has content
    590 		s.hasContent = !rnoContent.test( s.type );
    591 
    592 		// Save the URL in case we're toying with the If-Modified-Since
    593 		// and/or If-None-Match header later on
    594 		// Remove hash to simplify url manipulation
    595 		cacheURL = s.url.replace( rhash, "" );
    596 
    597 		// More options handling for requests with no content
    598 		if ( !s.hasContent ) {
    599 
    600 			// Remember the hash so we can put it back
    601 			uncached = s.url.slice( cacheURL.length );
    602 
    603 			// If data is available and should be processed, append data to url
    604 			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
    605 				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
    606 
    607 				// trac-9682: remove data so that it's not used in an eventual retry
    608 				delete s.data;
    609 			}
    610 
    611 			// Add or update anti-cache param if needed
    612 			if ( s.cache === false ) {
    613 				cacheURL = cacheURL.replace( rantiCache, "$1" );
    614 				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
    615 					uncached;
    616 			}
    617 
    618 			// Put hash and anti-cache on the URL that will be requested (gh-1732)
    619 			s.url = cacheURL + uncached;
    620 
    621 		// Change '%20' to '+' if this is encoded form body content (gh-2658)
    622 		} else if ( s.data && s.processData &&
    623 			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
    624 			s.data = s.data.replace( r20, "+" );
    625 		}
    626 
    627 		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
    628 		if ( s.ifModified ) {
    629 			if ( jQuery.lastModified[ cacheURL ] ) {
    630 				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
    631 			}
    632 			if ( jQuery.etag[ cacheURL ] ) {
    633 				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
    634 			}
    635 		}
    636 
    637 		// Set the correct header, if data is being sent
    638 		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
    639 			jqXHR.setRequestHeader( "Content-Type", s.contentType );
    640 		}
    641 
    642 		// Set the Accepts header for the server, depending on the dataType
    643 		jqXHR.setRequestHeader(
    644 			"Accept",
    645 			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
    646 				s.accepts[ s.dataTypes[ 0 ] ] +
    647 					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
    648 				s.accepts[ "*" ]
    649 		);
    650 
    651 		// Check for headers option
    652 		for ( i in s.headers ) {
    653 			jqXHR.setRequestHeader( i, s.headers[ i ] );
    654 		}
    655 
    656 		// Allow custom headers/mimetypes and early abort
    657 		if ( s.beforeSend &&
    658 			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
    659 
    660 			// Abort if not done already and return
    661 			return jqXHR.abort();
    662 		}
    663 
    664 		// Aborting is no longer a cancellation
    665 		strAbort = "abort";
    666 
    667 		// Install callbacks on deferreds
    668 		completeDeferred.add( s.complete );
    669 		jqXHR.done( s.success );
    670 		jqXHR.fail( s.error );
    671 
    672 		// Get transport
    673 		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
    674 
    675 		// If no transport, we auto-abort
    676 		if ( !transport ) {
    677 			done( -1, "No Transport" );
    678 		} else {
    679 			jqXHR.readyState = 1;
    680 
    681 			// Send global event
    682 			if ( fireGlobals ) {
    683 				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
    684 			}
    685 
    686 			// If request was aborted inside ajaxSend, stop there
    687 			if ( completed ) {
    688 				return jqXHR;
    689 			}
    690 
    691 			// Timeout
    692 			if ( s.async && s.timeout > 0 ) {
    693 				timeoutTimer = window.setTimeout( function() {
    694 					jqXHR.abort( "timeout" );
    695 				}, s.timeout );
    696 			}
    697 
    698 			try {
    699 				completed = false;
    700 				transport.send( requestHeaders, done );
    701 			} catch ( e ) {
    702 
    703 				// Rethrow post-completion exceptions
    704 				if ( completed ) {
    705 					throw e;
    706 				}
    707 
    708 				// Propagate others as results
    709 				done( -1, e );
    710 			}
    711 		}
    712 
    713 		// Callback for when everything is done
    714 		function done( status, nativeStatusText, responses, headers ) {
    715 			var isSuccess, success, error, response, modified,
    716 				statusText = nativeStatusText;
    717 
    718 			// Ignore repeat invocations
    719 			if ( completed ) {
    720 				return;
    721 			}
    722 
    723 			completed = true;
    724 
    725 			// Clear timeout if it exists
    726 			if ( timeoutTimer ) {
    727 				window.clearTimeout( timeoutTimer );
    728 			}
    729 
    730 			// Dereference transport for early garbage collection
    731 			// (no matter how long the jqXHR object will be used)
    732 			transport = undefined;
    733 
    734 			// Cache response headers
    735 			responseHeadersString = headers || "";
    736 
    737 			// Set readyState
    738 			jqXHR.readyState = status > 0 ? 4 : 0;
    739 
    740 			// Determine if successful
    741 			isSuccess = status >= 200 && status < 300 || status === 304;
    742 
    743 			// Get response data
    744 			if ( responses ) {
    745 				response = ajaxHandleResponses( s, jqXHR, responses );
    746 			}
    747 
    748 			// Use a noop converter for missing script but not if jsonp
    749 			if ( !isSuccess &&
    750 				jQuery.inArray( "script", s.dataTypes ) > -1 &&
    751 				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
    752 				s.converters[ "text script" ] = function() {};
    753 			}
    754 
    755 			// Convert no matter what (that way responseXXX fields are always set)
    756 			response = ajaxConvert( s, response, jqXHR, isSuccess );
    757 
    758 			// If successful, handle type chaining
    759 			if ( isSuccess ) {
    760 
    761 				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
    762 				if ( s.ifModified ) {
    763 					modified = jqXHR.getResponseHeader( "Last-Modified" );
    764 					if ( modified ) {
    765 						jQuery.lastModified[ cacheURL ] = modified;
    766 					}
    767 					modified = jqXHR.getResponseHeader( "etag" );
    768 					if ( modified ) {
    769 						jQuery.etag[ cacheURL ] = modified;
    770 					}
    771 				}
    772 
    773 				// if no content
    774 				if ( status === 204 || s.type === "HEAD" ) {
    775 					statusText = "nocontent";
    776 
    777 				// if not modified
    778 				} else if ( status === 304 ) {
    779 					statusText = "notmodified";
    780 
    781 				// If we have data, let's convert it
    782 				} else {
    783 					statusText = response.state;
    784 					success = response.data;
    785 					error = response.error;
    786 					isSuccess = !error;
    787 				}
    788 			} else {
    789 
    790 				// Extract error from statusText and normalize for non-aborts
    791 				error = statusText;
    792 				if ( status || !statusText ) {
    793 					statusText = "error";
    794 					if ( status < 0 ) {
    795 						status = 0;
    796 					}
    797 				}
    798 			}
    799 
    800 			// Set data for the fake xhr object
    801 			jqXHR.status = status;
    802 			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
    803 
    804 			// Success/Error
    805 			if ( isSuccess ) {
    806 				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
    807 			} else {
    808 				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
    809 			}
    810 
    811 			// Status-dependent callbacks
    812 			jqXHR.statusCode( statusCode );
    813 			statusCode = undefined;
    814 
    815 			if ( fireGlobals ) {
    816 				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
    817 					[ jqXHR, s, isSuccess ? success : error ] );
    818 			}
    819 
    820 			// Complete
    821 			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
    822 
    823 			if ( fireGlobals ) {
    824 				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
    825 
    826 				// Handle the global AJAX counter
    827 				if ( !( --jQuery.active ) ) {
    828 					jQuery.event.trigger( "ajaxStop" );
    829 				}
    830 			}
    831 		}
    832 
    833 		return jqXHR;
    834 	},
    835 
    836 	getJSON: function( url, data, callback ) {
    837 		return jQuery.get( url, data, callback, "json" );
    838 	},
    839 
    840 	getScript: function( url, callback ) {
    841 		return jQuery.get( url, undefined, callback, "script" );
    842 	}
    843 } );
    844 
    845 jQuery.each( [ "get", "post" ], function( _i, method ) {
    846 	jQuery[ method ] = function( url, data, callback, type ) {
    847 
    848 		// Shift arguments if data argument was omitted
    849 		if ( isFunction( data ) ) {
    850 			type = type || callback;
    851 			callback = data;
    852 			data = undefined;
    853 		}
    854 
    855 		// The url can be an options object (which then must have .url)
    856 		return jQuery.ajax( jQuery.extend( {
    857 			url: url,
    858 			type: method,
    859 			dataType: type,
    860 			data: data,
    861 			success: callback
    862 		}, jQuery.isPlainObject( url ) && url ) );
    863 	};
    864 } );
    865 
    866 jQuery.ajaxPrefilter( function( s ) {
    867 	var i;
    868 	for ( i in s.headers ) {
    869 		if ( i.toLowerCase() === "content-type" ) {
    870 			s.contentType = s.headers[ i ] || "";
    871 		}
    872 	}
    873 } );
    874 
    875 return jQuery;
    876 } );