| @@ 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" ); |
|