@@ 8355-8785 (lines=431) @@ | ||
8352 | ajaxTransport: addToPrefiltersOrTransports( transports ), |
|
8353 | ||
8354 | // Main method |
|
8355 | ajax: function( url, options ) { |
|
8356 | ||
8357 | // If url is an object, simulate pre-1.5 signature |
|
8358 | if ( typeof url === "object" ) { |
|
8359 | options = url; |
|
8360 | url = undefined; |
|
8361 | } |
|
8362 | ||
8363 | // Force options to be an object |
|
8364 | options = options || {}; |
|
8365 | ||
8366 | var transport, |
|
8367 | ||
8368 | // URL without anti-cache param |
|
8369 | cacheURL, |
|
8370 | ||
8371 | // Response headers |
|
8372 | responseHeadersString, |
|
8373 | responseHeaders, |
|
8374 | ||
8375 | // timeout handle |
|
8376 | timeoutTimer, |
|
8377 | ||
8378 | // Url cleanup var |
|
8379 | urlAnchor, |
|
8380 | ||
8381 | // To know if global events are to be dispatched |
|
8382 | fireGlobals, |
|
8383 | ||
8384 | // Loop variable |
|
8385 | i, |
|
8386 | ||
8387 | // Create the final options object |
|
8388 | s = jQuery.ajaxSetup( {}, options ), |
|
8389 | ||
8390 | // Callbacks context |
|
8391 | callbackContext = s.context || s, |
|
8392 | ||
8393 | // Context for global events is callbackContext if it is a DOM node or jQuery collection |
|
8394 | globalEventContext = s.context && |
|
8395 | ( callbackContext.nodeType || callbackContext.jquery ) ? |
|
8396 | jQuery( callbackContext ) : |
|
8397 | jQuery.event, |
|
8398 | ||
8399 | // Deferreds |
|
8400 | deferred = jQuery.Deferred(), |
|
8401 | completeDeferred = jQuery.Callbacks( "once memory" ), |
|
8402 | ||
8403 | // Status-dependent callbacks |
|
8404 | statusCode = s.statusCode || {}, |
|
8405 | ||
8406 | // Headers (they are sent all at once) |
|
8407 | requestHeaders = {}, |
|
8408 | requestHeadersNames = {}, |
|
8409 | ||
8410 | // The jqXHR state |
|
8411 | state = 0, |
|
8412 | ||
8413 | // Default abort message |
|
8414 | strAbort = "canceled", |
|
8415 | ||
8416 | // Fake xhr |
|
8417 | jqXHR = { |
|
8418 | readyState: 0, |
|
8419 | ||
8420 | // Builds headers hashtable if needed |
|
8421 | getResponseHeader: function( key ) { |
|
8422 | var match; |
|
8423 | if ( state === 2 ) { |
|
8424 | if ( !responseHeaders ) { |
|
8425 | responseHeaders = {}; |
|
8426 | while ( ( match = rheaders.exec( responseHeadersString ) ) ) { |
|
8427 | responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; |
|
8428 | } |
|
8429 | } |
|
8430 | match = responseHeaders[ key.toLowerCase() ]; |
|
8431 | } |
|
8432 | return match == null ? null : match; |
|
8433 | }, |
|
8434 | ||
8435 | // Raw string |
|
8436 | getAllResponseHeaders: function() { |
|
8437 | return state === 2 ? responseHeadersString : null; |
|
8438 | }, |
|
8439 | ||
8440 | // Caches the header |
|
8441 | setRequestHeader: function( name, value ) { |
|
8442 | var lname = name.toLowerCase(); |
|
8443 | if ( !state ) { |
|
8444 | name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; |
|
8445 | requestHeaders[ name ] = value; |
|
8446 | } |
|
8447 | return this; |
|
8448 | }, |
|
8449 | ||
8450 | // Overrides response content-type header |
|
8451 | overrideMimeType: function( type ) { |
|
8452 | if ( !state ) { |
|
8453 | s.mimeType = type; |
|
8454 | } |
|
8455 | return this; |
|
8456 | }, |
|
8457 | ||
8458 | // Status-dependent callbacks |
|
8459 | statusCode: function( map ) { |
|
8460 | var code; |
|
8461 | if ( map ) { |
|
8462 | if ( state < 2 ) { |
|
8463 | for ( code in map ) { |
|
8464 | ||
8465 | // Lazy-add the new callback in a way that preserves old ones |
|
8466 | statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; |
|
8467 | } |
|
8468 | } else { |
|
8469 | ||
8470 | // Execute the appropriate callbacks |
|
8471 | jqXHR.always( map[ jqXHR.status ] ); |
|
8472 | } |
|
8473 | } |
|
8474 | return this; |
|
8475 | }, |
|
8476 | ||
8477 | // Cancel the request |
|
8478 | abort: function( statusText ) { |
|
8479 | var finalText = statusText || strAbort; |
|
8480 | if ( transport ) { |
|
8481 | transport.abort( finalText ); |
|
8482 | } |
|
8483 | done( 0, finalText ); |
|
8484 | return this; |
|
8485 | } |
|
8486 | }; |
|
8487 | ||
8488 | // Attach deferreds |
|
8489 | deferred.promise( jqXHR ).complete = completeDeferred.add; |
|
8490 | jqXHR.success = jqXHR.done; |
|
8491 | jqXHR.error = jqXHR.fail; |
|
8492 | ||
8493 | // Remove hash character (#7531: and string promotion) |
|
8494 | // Add protocol if not provided (prefilters might expect it) |
|
8495 | // Handle falsy url in the settings object (#10093: consistency with old signature) |
|
8496 | // We also use the url parameter if available |
|
8497 | s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" ) |
|
8498 | .replace( rprotocol, location.protocol + "//" ); |
|
8499 | ||
8500 | // Alias method option to type as per ticket #12004 |
|
8501 | s.type = options.method || options.type || s.method || s.type; |
|
8502 | ||
8503 | // Extract dataTypes list |
|
8504 | s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; |
|
8505 | ||
8506 | // A cross-domain request is in order when the origin doesn't match the current origin. |
|
8507 | if ( s.crossDomain == null ) { |
|
8508 | urlAnchor = document.createElement( "a" ); |
|
8509 | ||
8510 | // Support: IE8-11+ |
|
8511 | // IE throws exception if url is malformed, e.g. http://example.com:80x/ |
|
8512 | try { |
|
8513 | urlAnchor.href = s.url; |
|
8514 | ||
8515 | // Support: IE8-11+ |
|
8516 | // Anchor's host property isn't correctly set when s.url is relative |
|
8517 | urlAnchor.href = urlAnchor.href; |
|
8518 | s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== |
|
8519 | urlAnchor.protocol + "//" + urlAnchor.host; |
|
8520 | } catch ( e ) { |
|
8521 | ||
8522 | // If there is an error parsing the URL, assume it is crossDomain, |
|
8523 | // it can be rejected by the transport if it is invalid |
|
8524 | s.crossDomain = true; |
|
8525 | } |
|
8526 | } |
|
8527 | ||
8528 | // Convert data if not already a string |
|
8529 | if ( s.data && s.processData && typeof s.data !== "string" ) { |
|
8530 | s.data = jQuery.param( s.data, s.traditional ); |
|
8531 | } |
|
8532 | ||
8533 | // Apply prefilters |
|
8534 | inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
|
8535 | ||
8536 | // If request was aborted inside a prefilter, stop there |
|
8537 | if ( state === 2 ) { |
|
8538 | return jqXHR; |
|
8539 | } |
|
8540 | ||
8541 | // We can fire global events as of now if asked to |
|
8542 | // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) |
|
8543 | fireGlobals = jQuery.event && s.global; |
|
8544 | ||
8545 | // Watch for a new set of requests |
|
8546 | if ( fireGlobals && jQuery.active++ === 0 ) { |
|
8547 | jQuery.event.trigger( "ajaxStart" ); |
|
8548 | } |
|
8549 | ||
8550 | // Uppercase the type |
|
8551 | s.type = s.type.toUpperCase(); |
|
8552 | ||
8553 | // Determine if request has content |
|
8554 | s.hasContent = !rnoContent.test( s.type ); |
|
8555 | ||
8556 | // Save the URL in case we're toying with the If-Modified-Since |
|
8557 | // and/or If-None-Match header later on |
|
8558 | cacheURL = s.url; |
|
8559 | ||
8560 | // More options handling for requests with no content |
|
8561 | if ( !s.hasContent ) { |
|
8562 | ||
8563 | // If data is available, append data to url |
|
8564 | if ( s.data ) { |
|
8565 | cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); |
|
8566 | ||
8567 | // #9682: remove data so that it's not used in an eventual retry |
|
8568 | delete s.data; |
|
8569 | } |
|
8570 | ||
8571 | // Add anti-cache in url if needed |
|
8572 | if ( s.cache === false ) { |
|
8573 | s.url = rts.test( cacheURL ) ? |
|
8574 | ||
8575 | // If there is already a '_' parameter, set its value |
|
8576 | cacheURL.replace( rts, "$1_=" + nonce++ ) : |
|
8577 | ||
8578 | // Otherwise add one to the end |
|
8579 | cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; |
|
8580 | } |
|
8581 | } |
|
8582 | ||
8583 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
8584 | if ( s.ifModified ) { |
|
8585 | if ( jQuery.lastModified[ cacheURL ] ) { |
|
8586 | jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); |
|
8587 | } |
|
8588 | if ( jQuery.etag[ cacheURL ] ) { |
|
8589 | jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); |
|
8590 | } |
|
8591 | } |
|
8592 | ||
8593 | // Set the correct header, if data is being sent |
|
8594 | if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { |
|
8595 | jqXHR.setRequestHeader( "Content-Type", s.contentType ); |
|
8596 | } |
|
8597 | ||
8598 | // Set the Accepts header for the server, depending on the dataType |
|
8599 | jqXHR.setRequestHeader( |
|
8600 | "Accept", |
|
8601 | s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? |
|
8602 | s.accepts[ s.dataTypes[ 0 ] ] + |
|
8603 | ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : |
|
8604 | s.accepts[ "*" ] |
|
8605 | ); |
|
8606 | ||
8607 | // Check for headers option |
|
8608 | for ( i in s.headers ) { |
|
8609 | jqXHR.setRequestHeader( i, s.headers[ i ] ); |
|
8610 | } |
|
8611 | ||
8612 | // Allow custom headers/mimetypes and early abort |
|
8613 | if ( s.beforeSend && |
|
8614 | ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { |
|
8615 | ||
8616 | // Abort if not done already and return |
|
8617 | return jqXHR.abort(); |
|
8618 | } |
|
8619 | ||
8620 | // Aborting is no longer a cancellation |
|
8621 | strAbort = "abort"; |
|
8622 | ||
8623 | // Install callbacks on deferreds |
|
8624 | for ( i in { success: 1, error: 1, complete: 1 } ) { |
|
8625 | jqXHR[ i ]( s[ i ] ); |
|
8626 | } |
|
8627 | ||
8628 | // Get transport |
|
8629 | transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
|
8630 | ||
8631 | // If no transport, we auto-abort |
|
8632 | if ( !transport ) { |
|
8633 | done( -1, "No Transport" ); |
|
8634 | } else { |
|
8635 | jqXHR.readyState = 1; |
|
8636 | ||
8637 | // Send global event |
|
8638 | if ( fireGlobals ) { |
|
8639 | globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
|
8640 | } |
|
8641 | ||
8642 | // If request was aborted inside ajaxSend, stop there |
|
8643 | if ( state === 2 ) { |
|
8644 | return jqXHR; |
|
8645 | } |
|
8646 | ||
8647 | // Timeout |
|
8648 | if ( s.async && s.timeout > 0 ) { |
|
8649 | timeoutTimer = window.setTimeout( function() { |
|
8650 | jqXHR.abort( "timeout" ); |
|
8651 | }, s.timeout ); |
|
8652 | } |
|
8653 | ||
8654 | try { |
|
8655 | state = 1; |
|
8656 | transport.send( requestHeaders, done ); |
|
8657 | } catch ( e ) { |
|
8658 | ||
8659 | // Propagate exception as error if not done |
|
8660 | if ( state < 2 ) { |
|
8661 | done( -1, e ); |
|
8662 | ||
8663 | // Simply rethrow otherwise |
|
8664 | } else { |
|
8665 | throw e; |
|
8666 | } |
|
8667 | } |
|
8668 | } |
|
8669 | ||
8670 | // Callback for when everything is done |
|
8671 | function done( status, nativeStatusText, responses, headers ) { |
|
8672 | var isSuccess, success, error, response, modified, |
|
8673 | statusText = nativeStatusText; |
|
8674 | ||
8675 | // Called once |
|
8676 | if ( state === 2 ) { |
|
8677 | return; |
|
8678 | } |
|
8679 | ||
8680 | // State is "done" now |
|
8681 | state = 2; |
|
8682 | ||
8683 | // Clear timeout if it exists |
|
8684 | if ( timeoutTimer ) { |
|
8685 | window.clearTimeout( timeoutTimer ); |
|
8686 | } |
|
8687 | ||
8688 | // Dereference transport for early garbage collection |
|
8689 | // (no matter how long the jqXHR object will be used) |
|
8690 | transport = undefined; |
|
8691 | ||
8692 | // Cache response headers |
|
8693 | responseHeadersString = headers || ""; |
|
8694 | ||
8695 | // Set readyState |
|
8696 | jqXHR.readyState = status > 0 ? 4 : 0; |
|
8697 | ||
8698 | // Determine if successful |
|
8699 | isSuccess = status >= 200 && status < 300 || status === 304; |
|
8700 | ||
8701 | // Get response data |
|
8702 | if ( responses ) { |
|
8703 | response = ajaxHandleResponses( s, jqXHR, responses ); |
|
8704 | } |
|
8705 | ||
8706 | // Convert no matter what (that way responseXXX fields are always set) |
|
8707 | response = ajaxConvert( s, response, jqXHR, isSuccess ); |
|
8708 | ||
8709 | // If successful, handle type chaining |
|
8710 | if ( isSuccess ) { |
|
8711 | ||
8712 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
8713 | if ( s.ifModified ) { |
|
8714 | modified = jqXHR.getResponseHeader( "Last-Modified" ); |
|
8715 | if ( modified ) { |
|
8716 | jQuery.lastModified[ cacheURL ] = modified; |
|
8717 | } |
|
8718 | modified = jqXHR.getResponseHeader( "etag" ); |
|
8719 | if ( modified ) { |
|
8720 | jQuery.etag[ cacheURL ] = modified; |
|
8721 | } |
|
8722 | } |
|
8723 | ||
8724 | // if no content |
|
8725 | if ( status === 204 || s.type === "HEAD" ) { |
|
8726 | statusText = "nocontent"; |
|
8727 | ||
8728 | // if not modified |
|
8729 | } else if ( status === 304 ) { |
|
8730 | statusText = "notmodified"; |
|
8731 | ||
8732 | // If we have data, let's convert it |
|
8733 | } else { |
|
8734 | statusText = response.state; |
|
8735 | success = response.data; |
|
8736 | error = response.error; |
|
8737 | isSuccess = !error; |
|
8738 | } |
|
8739 | } else { |
|
8740 | ||
8741 | // Extract error from statusText and normalize for non-aborts |
|
8742 | error = statusText; |
|
8743 | if ( status || !statusText ) { |
|
8744 | statusText = "error"; |
|
8745 | if ( status < 0 ) { |
|
8746 | status = 0; |
|
8747 | } |
|
8748 | } |
|
8749 | } |
|
8750 | ||
8751 | // Set data for the fake xhr object |
|
8752 | jqXHR.status = status; |
|
8753 | jqXHR.statusText = ( nativeStatusText || statusText ) + ""; |
|
8754 | ||
8755 | // Success/Error |
|
8756 | if ( isSuccess ) { |
|
8757 | deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
|
8758 | } else { |
|
8759 | deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
|
8760 | } |
|
8761 | ||
8762 | // Status-dependent callbacks |
|
8763 | jqXHR.statusCode( statusCode ); |
|
8764 | statusCode = undefined; |
|
8765 | ||
8766 | if ( fireGlobals ) { |
|
8767 | globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", |
|
8768 | [ jqXHR, s, isSuccess ? success : error ] ); |
|
8769 | } |
|
8770 | ||
8771 | // Complete |
|
8772 | completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); |
|
8773 | ||
8774 | if ( fireGlobals ) { |
|
8775 | globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); |
|
8776 | ||
8777 | // Handle the global AJAX counter |
|
8778 | if ( !( --jQuery.active ) ) { |
|
8779 | jQuery.event.trigger( "ajaxStop" ); |
|
8780 | } |
|
8781 | } |
|
8782 | } |
|
8783 | ||
8784 | return jqXHR; |
|
8785 | }, |
|
8786 | ||
8787 | getJSON: function( url, data, callback ) { |
|
8788 | return jQuery.get( url, data, callback, "json" ); |
@@ 9440-9864 (lines=425) @@ | ||
9437 | ajaxTransport: addToPrefiltersOrTransports( transports ), |
|
9438 | ||
9439 | // Main method |
|
9440 | ajax: function( url, options ) { |
|
9441 | ||
9442 | // If url is an object, simulate pre-1.5 signature |
|
9443 | if ( typeof url === "object" ) { |
|
9444 | options = url; |
|
9445 | url = undefined; |
|
9446 | } |
|
9447 | ||
9448 | // Force options to be an object |
|
9449 | options = options || {}; |
|
9450 | ||
9451 | var |
|
9452 | ||
9453 | // Cross-domain detection vars |
|
9454 | parts, |
|
9455 | ||
9456 | // Loop variable |
|
9457 | i, |
|
9458 | ||
9459 | // URL without anti-cache param |
|
9460 | cacheURL, |
|
9461 | ||
9462 | // Response headers as string |
|
9463 | responseHeadersString, |
|
9464 | ||
9465 | // timeout handle |
|
9466 | timeoutTimer, |
|
9467 | ||
9468 | // To know if global events are to be dispatched |
|
9469 | fireGlobals, |
|
9470 | ||
9471 | transport, |
|
9472 | ||
9473 | // Response headers |
|
9474 | responseHeaders, |
|
9475 | ||
9476 | // Create the final options object |
|
9477 | s = jQuery.ajaxSetup( {}, options ), |
|
9478 | ||
9479 | // Callbacks context |
|
9480 | callbackContext = s.context || s, |
|
9481 | ||
9482 | // Context for global events is callbackContext if it is a DOM node or jQuery collection |
|
9483 | globalEventContext = s.context && |
|
9484 | ( callbackContext.nodeType || callbackContext.jquery ) ? |
|
9485 | jQuery( callbackContext ) : |
|
9486 | jQuery.event, |
|
9487 | ||
9488 | // Deferreds |
|
9489 | deferred = jQuery.Deferred(), |
|
9490 | completeDeferred = jQuery.Callbacks( "once memory" ), |
|
9491 | ||
9492 | // Status-dependent callbacks |
|
9493 | statusCode = s.statusCode || {}, |
|
9494 | ||
9495 | // Headers (they are sent all at once) |
|
9496 | requestHeaders = {}, |
|
9497 | requestHeadersNames = {}, |
|
9498 | ||
9499 | // The jqXHR state |
|
9500 | state = 0, |
|
9501 | ||
9502 | // Default abort message |
|
9503 | strAbort = "canceled", |
|
9504 | ||
9505 | // Fake xhr |
|
9506 | jqXHR = { |
|
9507 | readyState: 0, |
|
9508 | ||
9509 | // Builds headers hashtable if needed |
|
9510 | getResponseHeader: function( key ) { |
|
9511 | var match; |
|
9512 | if ( state === 2 ) { |
|
9513 | if ( !responseHeaders ) { |
|
9514 | responseHeaders = {}; |
|
9515 | while ( ( match = rheaders.exec( responseHeadersString ) ) ) { |
|
9516 | responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; |
|
9517 | } |
|
9518 | } |
|
9519 | match = responseHeaders[ key.toLowerCase() ]; |
|
9520 | } |
|
9521 | return match == null ? null : match; |
|
9522 | }, |
|
9523 | ||
9524 | // Raw string |
|
9525 | getAllResponseHeaders: function() { |
|
9526 | return state === 2 ? responseHeadersString : null; |
|
9527 | }, |
|
9528 | ||
9529 | // Caches the header |
|
9530 | setRequestHeader: function( name, value ) { |
|
9531 | var lname = name.toLowerCase(); |
|
9532 | if ( !state ) { |
|
9533 | name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; |
|
9534 | requestHeaders[ name ] = value; |
|
9535 | } |
|
9536 | return this; |
|
9537 | }, |
|
9538 | ||
9539 | // Overrides response content-type header |
|
9540 | overrideMimeType: function( type ) { |
|
9541 | if ( !state ) { |
|
9542 | s.mimeType = type; |
|
9543 | } |
|
9544 | return this; |
|
9545 | }, |
|
9546 | ||
9547 | // Status-dependent callbacks |
|
9548 | statusCode: function( map ) { |
|
9549 | var code; |
|
9550 | if ( map ) { |
|
9551 | if ( state < 2 ) { |
|
9552 | for ( code in map ) { |
|
9553 | ||
9554 | // Lazy-add the new callback in a way that preserves old ones |
|
9555 | statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; |
|
9556 | } |
|
9557 | } else { |
|
9558 | ||
9559 | // Execute the appropriate callbacks |
|
9560 | jqXHR.always( map[ jqXHR.status ] ); |
|
9561 | } |
|
9562 | } |
|
9563 | return this; |
|
9564 | }, |
|
9565 | ||
9566 | // Cancel the request |
|
9567 | abort: function( statusText ) { |
|
9568 | var finalText = statusText || strAbort; |
|
9569 | if ( transport ) { |
|
9570 | transport.abort( finalText ); |
|
9571 | } |
|
9572 | done( 0, finalText ); |
|
9573 | return this; |
|
9574 | } |
|
9575 | }; |
|
9576 | ||
9577 | // Attach deferreds |
|
9578 | deferred.promise( jqXHR ).complete = completeDeferred.add; |
|
9579 | jqXHR.success = jqXHR.done; |
|
9580 | jqXHR.error = jqXHR.fail; |
|
9581 | ||
9582 | // Remove hash character (#7531: and string promotion) |
|
9583 | // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) |
|
9584 | // Handle falsy url in the settings object (#10093: consistency with old signature) |
|
9585 | // We also use the url parameter if available |
|
9586 | s.url = ( ( url || s.url || ajaxLocation ) + "" ) |
|
9587 | .replace( rhash, "" ) |
|
9588 | .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); |
|
9589 | ||
9590 | // Alias method option to type as per ticket #12004 |
|
9591 | s.type = options.method || options.type || s.method || s.type; |
|
9592 | ||
9593 | // Extract dataTypes list |
|
9594 | s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; |
|
9595 | ||
9596 | // A cross-domain request is in order when we have a protocol:host:port mismatch |
|
9597 | if ( s.crossDomain == null ) { |
|
9598 | parts = rurl.exec( s.url.toLowerCase() ); |
|
9599 | s.crossDomain = !!( parts && |
|
9600 | ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || |
|
9601 | ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== |
|
9602 | ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) |
|
9603 | ); |
|
9604 | } |
|
9605 | ||
9606 | // Convert data if not already a string |
|
9607 | if ( s.data && s.processData && typeof s.data !== "string" ) { |
|
9608 | s.data = jQuery.param( s.data, s.traditional ); |
|
9609 | } |
|
9610 | ||
9611 | // Apply prefilters |
|
9612 | inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
|
9613 | ||
9614 | // If request was aborted inside a prefilter, stop there |
|
9615 | if ( state === 2 ) { |
|
9616 | return jqXHR; |
|
9617 | } |
|
9618 | ||
9619 | // We can fire global events as of now if asked to |
|
9620 | // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) |
|
9621 | fireGlobals = jQuery.event && s.global; |
|
9622 | ||
9623 | // Watch for a new set of requests |
|
9624 | if ( fireGlobals && jQuery.active++ === 0 ) { |
|
9625 | jQuery.event.trigger( "ajaxStart" ); |
|
9626 | } |
|
9627 | ||
9628 | // Uppercase the type |
|
9629 | s.type = s.type.toUpperCase(); |
|
9630 | ||
9631 | // Determine if request has content |
|
9632 | s.hasContent = !rnoContent.test( s.type ); |
|
9633 | ||
9634 | // Save the URL in case we're toying with the If-Modified-Since |
|
9635 | // and/or If-None-Match header later on |
|
9636 | cacheURL = s.url; |
|
9637 | ||
9638 | // More options handling for requests with no content |
|
9639 | if ( !s.hasContent ) { |
|
9640 | ||
9641 | // If data is available, append data to url |
|
9642 | if ( s.data ) { |
|
9643 | cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); |
|
9644 | ||
9645 | // #9682: remove data so that it's not used in an eventual retry |
|
9646 | delete s.data; |
|
9647 | } |
|
9648 | ||
9649 | // Add anti-cache in url if needed |
|
9650 | if ( s.cache === false ) { |
|
9651 | s.url = rts.test( cacheURL ) ? |
|
9652 | ||
9653 | // If there is already a '_' parameter, set its value |
|
9654 | cacheURL.replace( rts, "$1_=" + nonce++ ) : |
|
9655 | ||
9656 | // Otherwise add one to the end |
|
9657 | cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; |
|
9658 | } |
|
9659 | } |
|
9660 | ||
9661 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
9662 | if ( s.ifModified ) { |
|
9663 | if ( jQuery.lastModified[ cacheURL ] ) { |
|
9664 | jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); |
|
9665 | } |
|
9666 | if ( jQuery.etag[ cacheURL ] ) { |
|
9667 | jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); |
|
9668 | } |
|
9669 | } |
|
9670 | ||
9671 | // Set the correct header, if data is being sent |
|
9672 | if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { |
|
9673 | jqXHR.setRequestHeader( "Content-Type", s.contentType ); |
|
9674 | } |
|
9675 | ||
9676 | // Set the Accepts header for the server, depending on the dataType |
|
9677 | jqXHR.setRequestHeader( |
|
9678 | "Accept", |
|
9679 | s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? |
|
9680 | s.accepts[ s.dataTypes[ 0 ] ] + |
|
9681 | ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : |
|
9682 | s.accepts[ "*" ] |
|
9683 | ); |
|
9684 | ||
9685 | // Check for headers option |
|
9686 | for ( i in s.headers ) { |
|
9687 | jqXHR.setRequestHeader( i, s.headers[ i ] ); |
|
9688 | } |
|
9689 | ||
9690 | // Allow custom headers/mimetypes and early abort |
|
9691 | if ( s.beforeSend && |
|
9692 | ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { |
|
9693 | ||
9694 | // Abort if not done already and return |
|
9695 | return jqXHR.abort(); |
|
9696 | } |
|
9697 | ||
9698 | // aborting is no longer a cancellation |
|
9699 | strAbort = "abort"; |
|
9700 | ||
9701 | // Install callbacks on deferreds |
|
9702 | for ( i in { success: 1, error: 1, complete: 1 } ) { |
|
9703 | jqXHR[ i ]( s[ i ] ); |
|
9704 | } |
|
9705 | ||
9706 | // Get transport |
|
9707 | transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
|
9708 | ||
9709 | // If no transport, we auto-abort |
|
9710 | if ( !transport ) { |
|
9711 | done( -1, "No Transport" ); |
|
9712 | } else { |
|
9713 | jqXHR.readyState = 1; |
|
9714 | ||
9715 | // Send global event |
|
9716 | if ( fireGlobals ) { |
|
9717 | globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
|
9718 | } |
|
9719 | ||
9720 | // If request was aborted inside ajaxSend, stop there |
|
9721 | if ( state === 2 ) { |
|
9722 | return jqXHR; |
|
9723 | } |
|
9724 | ||
9725 | // Timeout |
|
9726 | if ( s.async && s.timeout > 0 ) { |
|
9727 | timeoutTimer = window.setTimeout( function() { |
|
9728 | jqXHR.abort( "timeout" ); |
|
9729 | }, s.timeout ); |
|
9730 | } |
|
9731 | ||
9732 | try { |
|
9733 | state = 1; |
|
9734 | transport.send( requestHeaders, done ); |
|
9735 | } catch ( e ) { |
|
9736 | ||
9737 | // Propagate exception as error if not done |
|
9738 | if ( state < 2 ) { |
|
9739 | done( -1, e ); |
|
9740 | ||
9741 | // Simply rethrow otherwise |
|
9742 | } else { |
|
9743 | throw e; |
|
9744 | } |
|
9745 | } |
|
9746 | } |
|
9747 | ||
9748 | // Callback for when everything is done |
|
9749 | function done( status, nativeStatusText, responses, headers ) { |
|
9750 | var isSuccess, success, error, response, modified, |
|
9751 | statusText = nativeStatusText; |
|
9752 | ||
9753 | // Called once |
|
9754 | if ( state === 2 ) { |
|
9755 | return; |
|
9756 | } |
|
9757 | ||
9758 | // State is "done" now |
|
9759 | state = 2; |
|
9760 | ||
9761 | // Clear timeout if it exists |
|
9762 | if ( timeoutTimer ) { |
|
9763 | window.clearTimeout( timeoutTimer ); |
|
9764 | } |
|
9765 | ||
9766 | // Dereference transport for early garbage collection |
|
9767 | // (no matter how long the jqXHR object will be used) |
|
9768 | transport = undefined; |
|
9769 | ||
9770 | // Cache response headers |
|
9771 | responseHeadersString = headers || ""; |
|
9772 | ||
9773 | // Set readyState |
|
9774 | jqXHR.readyState = status > 0 ? 4 : 0; |
|
9775 | ||
9776 | // Determine if successful |
|
9777 | isSuccess = status >= 200 && status < 300 || status === 304; |
|
9778 | ||
9779 | // Get response data |
|
9780 | if ( responses ) { |
|
9781 | response = ajaxHandleResponses( s, jqXHR, responses ); |
|
9782 | } |
|
9783 | ||
9784 | // Convert no matter what (that way responseXXX fields are always set) |
|
9785 | response = ajaxConvert( s, response, jqXHR, isSuccess ); |
|
9786 | ||
9787 | // If successful, handle type chaining |
|
9788 | if ( isSuccess ) { |
|
9789 | ||
9790 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
9791 | if ( s.ifModified ) { |
|
9792 | modified = jqXHR.getResponseHeader( "Last-Modified" ); |
|
9793 | if ( modified ) { |
|
9794 | jQuery.lastModified[ cacheURL ] = modified; |
|
9795 | } |
|
9796 | modified = jqXHR.getResponseHeader( "etag" ); |
|
9797 | if ( modified ) { |
|
9798 | jQuery.etag[ cacheURL ] = modified; |
|
9799 | } |
|
9800 | } |
|
9801 | ||
9802 | // if no content |
|
9803 | if ( status === 204 || s.type === "HEAD" ) { |
|
9804 | statusText = "nocontent"; |
|
9805 | ||
9806 | // if not modified |
|
9807 | } else if ( status === 304 ) { |
|
9808 | statusText = "notmodified"; |
|
9809 | ||
9810 | // If we have data, let's convert it |
|
9811 | } else { |
|
9812 | statusText = response.state; |
|
9813 | success = response.data; |
|
9814 | error = response.error; |
|
9815 | isSuccess = !error; |
|
9816 | } |
|
9817 | } else { |
|
9818 | ||
9819 | // We extract error from statusText |
|
9820 | // then normalize statusText and status for non-aborts |
|
9821 | error = statusText; |
|
9822 | if ( status || !statusText ) { |
|
9823 | statusText = "error"; |
|
9824 | if ( status < 0 ) { |
|
9825 | status = 0; |
|
9826 | } |
|
9827 | } |
|
9828 | } |
|
9829 | ||
9830 | // Set data for the fake xhr object |
|
9831 | jqXHR.status = status; |
|
9832 | jqXHR.statusText = ( nativeStatusText || statusText ) + ""; |
|
9833 | ||
9834 | // Success/Error |
|
9835 | if ( isSuccess ) { |
|
9836 | deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
|
9837 | } else { |
|
9838 | deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
|
9839 | } |
|
9840 | ||
9841 | // Status-dependent callbacks |
|
9842 | jqXHR.statusCode( statusCode ); |
|
9843 | statusCode = undefined; |
|
9844 | ||
9845 | if ( fireGlobals ) { |
|
9846 | globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", |
|
9847 | [ jqXHR, s, isSuccess ? success : error ] ); |
|
9848 | } |
|
9849 | ||
9850 | // Complete |
|
9851 | completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); |
|
9852 | ||
9853 | if ( fireGlobals ) { |
|
9854 | globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); |
|
9855 | ||
9856 | // Handle the global AJAX counter |
|
9857 | if ( !( --jQuery.active ) ) { |
|
9858 | jQuery.event.trigger( "ajaxStop" ); |
|
9859 | } |
|
9860 | } |
|
9861 | } |
|
9862 | ||
9863 | return jqXHR; |
|
9864 | }, |
|
9865 | ||
9866 | getJSON: function( url, data, callback ) { |
|
9867 | return jQuery.get( url, data, callback, "json" ); |
@@ 7892-8278 (lines=387) @@ | ||
7889 | ajaxTransport: addToPrefiltersOrTransports( transports ), |
|
7890 | ||
7891 | // Main method |
|
7892 | ajax: function( url, options ) { |
|
7893 | ||
7894 | // If url is an object, simulate pre-1.5 signature |
|
7895 | if ( typeof url === "object" ) { |
|
7896 | options = url; |
|
7897 | url = undefined; |
|
7898 | } |
|
7899 | ||
7900 | // Force options to be an object |
|
7901 | options = options || {}; |
|
7902 | ||
7903 | var transport, |
|
7904 | // URL without anti-cache param |
|
7905 | cacheURL, |
|
7906 | // Response headers |
|
7907 | responseHeadersString, |
|
7908 | responseHeaders, |
|
7909 | // timeout handle |
|
7910 | timeoutTimer, |
|
7911 | // Cross-domain detection vars |
|
7912 | parts, |
|
7913 | // To know if global events are to be dispatched |
|
7914 | fireGlobals, |
|
7915 | // Loop variable |
|
7916 | i, |
|
7917 | // Create the final options object |
|
7918 | s = jQuery.ajaxSetup( {}, options ), |
|
7919 | // Callbacks context |
|
7920 | callbackContext = s.context || s, |
|
7921 | // Context for global events is callbackContext if it is a DOM node or jQuery collection |
|
7922 | globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? |
|
7923 | jQuery( callbackContext ) : |
|
7924 | jQuery.event, |
|
7925 | // Deferreds |
|
7926 | deferred = jQuery.Deferred(), |
|
7927 | completeDeferred = jQuery.Callbacks("once memory"), |
|
7928 | // Status-dependent callbacks |
|
7929 | statusCode = s.statusCode || {}, |
|
7930 | // Headers (they are sent all at once) |
|
7931 | requestHeaders = {}, |
|
7932 | requestHeadersNames = {}, |
|
7933 | // The jqXHR state |
|
7934 | state = 0, |
|
7935 | // Default abort message |
|
7936 | strAbort = "canceled", |
|
7937 | // Fake xhr |
|
7938 | jqXHR = { |
|
7939 | readyState: 0, |
|
7940 | ||
7941 | // Builds headers hashtable if needed |
|
7942 | getResponseHeader: function( key ) { |
|
7943 | var match; |
|
7944 | if ( state === 2 ) { |
|
7945 | if ( !responseHeaders ) { |
|
7946 | responseHeaders = {}; |
|
7947 | while ( (match = rheaders.exec( responseHeadersString )) ) { |
|
7948 | responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; |
|
7949 | } |
|
7950 | } |
|
7951 | match = responseHeaders[ key.toLowerCase() ]; |
|
7952 | } |
|
7953 | return match == null ? null : match; |
|
7954 | }, |
|
7955 | ||
7956 | // Raw string |
|
7957 | getAllResponseHeaders: function() { |
|
7958 | return state === 2 ? responseHeadersString : null; |
|
7959 | }, |
|
7960 | ||
7961 | // Caches the header |
|
7962 | setRequestHeader: function( name, value ) { |
|
7963 | var lname = name.toLowerCase(); |
|
7964 | if ( !state ) { |
|
7965 | name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; |
|
7966 | requestHeaders[ name ] = value; |
|
7967 | } |
|
7968 | return this; |
|
7969 | }, |
|
7970 | ||
7971 | // Overrides response content-type header |
|
7972 | overrideMimeType: function( type ) { |
|
7973 | if ( !state ) { |
|
7974 | s.mimeType = type; |
|
7975 | } |
|
7976 | return this; |
|
7977 | }, |
|
7978 | ||
7979 | // Status-dependent callbacks |
|
7980 | statusCode: function( map ) { |
|
7981 | var code; |
|
7982 | if ( map ) { |
|
7983 | if ( state < 2 ) { |
|
7984 | for ( code in map ) { |
|
7985 | // Lazy-add the new callback in a way that preserves old ones |
|
7986 | statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; |
|
7987 | } |
|
7988 | } else { |
|
7989 | // Execute the appropriate callbacks |
|
7990 | jqXHR.always( map[ jqXHR.status ] ); |
|
7991 | } |
|
7992 | } |
|
7993 | return this; |
|
7994 | }, |
|
7995 | ||
7996 | // Cancel the request |
|
7997 | abort: function( statusText ) { |
|
7998 | var finalText = statusText || strAbort; |
|
7999 | if ( transport ) { |
|
8000 | transport.abort( finalText ); |
|
8001 | } |
|
8002 | done( 0, finalText ); |
|
8003 | return this; |
|
8004 | } |
|
8005 | }; |
|
8006 | ||
8007 | // Attach deferreds |
|
8008 | deferred.promise( jqXHR ).complete = completeDeferred.add; |
|
8009 | jqXHR.success = jqXHR.done; |
|
8010 | jqXHR.error = jqXHR.fail; |
|
8011 | ||
8012 | // Remove hash character (#7531: and string promotion) |
|
8013 | // Add protocol if not provided (prefilters might expect it) |
|
8014 | // Handle falsy url in the settings object (#10093: consistency with old signature) |
|
8015 | // We also use the url parameter if available |
|
8016 | s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) |
|
8017 | .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); |
|
8018 | ||
8019 | // Alias method option to type as per ticket #12004 |
|
8020 | s.type = options.method || options.type || s.method || s.type; |
|
8021 | ||
8022 | // Extract dataTypes list |
|
8023 | s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; |
|
8024 | ||
8025 | // A cross-domain request is in order when we have a protocol:host:port mismatch |
|
8026 | if ( s.crossDomain == null ) { |
|
8027 | parts = rurl.exec( s.url.toLowerCase() ); |
|
8028 | s.crossDomain = !!( parts && |
|
8029 | ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || |
|
8030 | ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== |
|
8031 | ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) |
|
8032 | ); |
|
8033 | } |
|
8034 | ||
8035 | // Convert data if not already a string |
|
8036 | if ( s.data && s.processData && typeof s.data !== "string" ) { |
|
8037 | s.data = jQuery.param( s.data, s.traditional ); |
|
8038 | } |
|
8039 | ||
8040 | // Apply prefilters |
|
8041 | inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
|
8042 | ||
8043 | // If request was aborted inside a prefilter, stop there |
|
8044 | if ( state === 2 ) { |
|
8045 | return jqXHR; |
|
8046 | } |
|
8047 | ||
8048 | // We can fire global events as of now if asked to |
|
8049 | fireGlobals = s.global; |
|
8050 | ||
8051 | // Watch for a new set of requests |
|
8052 | if ( fireGlobals && jQuery.active++ === 0 ) { |
|
8053 | jQuery.event.trigger("ajaxStart"); |
|
8054 | } |
|
8055 | ||
8056 | // Uppercase the type |
|
8057 | s.type = s.type.toUpperCase(); |
|
8058 | ||
8059 | // Determine if request has content |
|
8060 | s.hasContent = !rnoContent.test( s.type ); |
|
8061 | ||
8062 | // Save the URL in case we're toying with the If-Modified-Since |
|
8063 | // and/or If-None-Match header later on |
|
8064 | cacheURL = s.url; |
|
8065 | ||
8066 | // More options handling for requests with no content |
|
8067 | if ( !s.hasContent ) { |
|
8068 | ||
8069 | // If data is available, append data to url |
|
8070 | if ( s.data ) { |
|
8071 | cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); |
|
8072 | // #9682: remove data so that it's not used in an eventual retry |
|
8073 | delete s.data; |
|
8074 | } |
|
8075 | ||
8076 | // Add anti-cache in url if needed |
|
8077 | if ( s.cache === false ) { |
|
8078 | s.url = rts.test( cacheURL ) ? |
|
8079 | ||
8080 | // If there is already a '_' parameter, set its value |
|
8081 | cacheURL.replace( rts, "$1_=" + nonce++ ) : |
|
8082 | ||
8083 | // Otherwise add one to the end |
|
8084 | cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; |
|
8085 | } |
|
8086 | } |
|
8087 | ||
8088 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
8089 | if ( s.ifModified ) { |
|
8090 | if ( jQuery.lastModified[ cacheURL ] ) { |
|
8091 | jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); |
|
8092 | } |
|
8093 | if ( jQuery.etag[ cacheURL ] ) { |
|
8094 | jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); |
|
8095 | } |
|
8096 | } |
|
8097 | ||
8098 | // Set the correct header, if data is being sent |
|
8099 | if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { |
|
8100 | jqXHR.setRequestHeader( "Content-Type", s.contentType ); |
|
8101 | } |
|
8102 | ||
8103 | // Set the Accepts header for the server, depending on the dataType |
|
8104 | jqXHR.setRequestHeader( |
|
8105 | "Accept", |
|
8106 | s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? |
|
8107 | s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : |
|
8108 | s.accepts[ "*" ] |
|
8109 | ); |
|
8110 | ||
8111 | // Check for headers option |
|
8112 | for ( i in s.headers ) { |
|
8113 | jqXHR.setRequestHeader( i, s.headers[ i ] ); |
|
8114 | } |
|
8115 | ||
8116 | // Allow custom headers/mimetypes and early abort |
|
8117 | if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { |
|
8118 | // Abort if not done already and return |
|
8119 | return jqXHR.abort(); |
|
8120 | } |
|
8121 | ||
8122 | // aborting is no longer a cancellation |
|
8123 | strAbort = "abort"; |
|
8124 | ||
8125 | // Install callbacks on deferreds |
|
8126 | for ( i in { success: 1, error: 1, complete: 1 } ) { |
|
8127 | jqXHR[ i ]( s[ i ] ); |
|
8128 | } |
|
8129 | ||
8130 | // Get transport |
|
8131 | transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
|
8132 | ||
8133 | // If no transport, we auto-abort |
|
8134 | if ( !transport ) { |
|
8135 | done( -1, "No Transport" ); |
|
8136 | } else { |
|
8137 | jqXHR.readyState = 1; |
|
8138 | ||
8139 | // Send global event |
|
8140 | if ( fireGlobals ) { |
|
8141 | globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
|
8142 | } |
|
8143 | // Timeout |
|
8144 | if ( s.async && s.timeout > 0 ) { |
|
8145 | timeoutTimer = setTimeout(function() { |
|
8146 | jqXHR.abort("timeout"); |
|
8147 | }, s.timeout ); |
|
8148 | } |
|
8149 | ||
8150 | try { |
|
8151 | state = 1; |
|
8152 | transport.send( requestHeaders, done ); |
|
8153 | } catch ( e ) { |
|
8154 | // Propagate exception as error if not done |
|
8155 | if ( state < 2 ) { |
|
8156 | done( -1, e ); |
|
8157 | // Simply rethrow otherwise |
|
8158 | } else { |
|
8159 | throw e; |
|
8160 | } |
|
8161 | } |
|
8162 | } |
|
8163 | ||
8164 | // Callback for when everything is done |
|
8165 | function done( status, nativeStatusText, responses, headers ) { |
|
8166 | var isSuccess, success, error, response, modified, |
|
8167 | statusText = nativeStatusText; |
|
8168 | ||
8169 | // Called once |
|
8170 | if ( state === 2 ) { |
|
8171 | return; |
|
8172 | } |
|
8173 | ||
8174 | // State is "done" now |
|
8175 | state = 2; |
|
8176 | ||
8177 | // Clear timeout if it exists |
|
8178 | if ( timeoutTimer ) { |
|
8179 | clearTimeout( timeoutTimer ); |
|
8180 | } |
|
8181 | ||
8182 | // Dereference transport for early garbage collection |
|
8183 | // (no matter how long the jqXHR object will be used) |
|
8184 | transport = undefined; |
|
8185 | ||
8186 | // Cache response headers |
|
8187 | responseHeadersString = headers || ""; |
|
8188 | ||
8189 | // Set readyState |
|
8190 | jqXHR.readyState = status > 0 ? 4 : 0; |
|
8191 | ||
8192 | // Determine if successful |
|
8193 | isSuccess = status >= 200 && status < 300 || status === 304; |
|
8194 | ||
8195 | // Get response data |
|
8196 | if ( responses ) { |
|
8197 | response = ajaxHandleResponses( s, jqXHR, responses ); |
|
8198 | } |
|
8199 | ||
8200 | // Convert no matter what (that way responseXXX fields are always set) |
|
8201 | response = ajaxConvert( s, response, jqXHR, isSuccess ); |
|
8202 | ||
8203 | // If successful, handle type chaining |
|
8204 | if ( isSuccess ) { |
|
8205 | ||
8206 | // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
8207 | if ( s.ifModified ) { |
|
8208 | modified = jqXHR.getResponseHeader("Last-Modified"); |
|
8209 | if ( modified ) { |
|
8210 | jQuery.lastModified[ cacheURL ] = modified; |
|
8211 | } |
|
8212 | modified = jqXHR.getResponseHeader("etag"); |
|
8213 | if ( modified ) { |
|
8214 | jQuery.etag[ cacheURL ] = modified; |
|
8215 | } |
|
8216 | } |
|
8217 | ||
8218 | // if no content |
|
8219 | if ( status === 204 || s.type === "HEAD" ) { |
|
8220 | statusText = "nocontent"; |
|
8221 | ||
8222 | // if not modified |
|
8223 | } else if ( status === 304 ) { |
|
8224 | statusText = "notmodified"; |
|
8225 | ||
8226 | // If we have data, let's convert it |
|
8227 | } else { |
|
8228 | statusText = response.state; |
|
8229 | success = response.data; |
|
8230 | error = response.error; |
|
8231 | isSuccess = !error; |
|
8232 | } |
|
8233 | } else { |
|
8234 | // We extract error from statusText |
|
8235 | // then normalize statusText and status for non-aborts |
|
8236 | error = statusText; |
|
8237 | if ( status || !statusText ) { |
|
8238 | statusText = "error"; |
|
8239 | if ( status < 0 ) { |
|
8240 | status = 0; |
|
8241 | } |
|
8242 | } |
|
8243 | } |
|
8244 | ||
8245 | // Set data for the fake xhr object |
|
8246 | jqXHR.status = status; |
|
8247 | jqXHR.statusText = ( nativeStatusText || statusText ) + ""; |
|
8248 | ||
8249 | // Success/Error |
|
8250 | if ( isSuccess ) { |
|
8251 | deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
|
8252 | } else { |
|
8253 | deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
|
8254 | } |
|
8255 | ||
8256 | // Status-dependent callbacks |
|
8257 | jqXHR.statusCode( statusCode ); |
|
8258 | statusCode = undefined; |
|
8259 | ||
8260 | if ( fireGlobals ) { |
|
8261 | globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", |
|
8262 | [ jqXHR, s, isSuccess ? success : error ] ); |
|
8263 | } |
|
8264 | ||
8265 | // Complete |
|
8266 | completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); |
|
8267 | ||
8268 | if ( fireGlobals ) { |
|
8269 | globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); |
|
8270 | // Handle the global AJAX counter |
|
8271 | if ( !( --jQuery.active ) ) { |
|
8272 | jQuery.event.trigger("ajaxStop"); |
|
8273 | } |
|
8274 | } |
|
8275 | } |
|
8276 | ||
8277 | return jqXHR; |
|
8278 | }, |
|
8279 | ||
8280 | getJSON: function( url, data, callback ) { |
|
8281 | return jQuery.get( url, data, callback, "json" ); |