jsonp.js (2753B)
1 define( [ 2 "../core", 3 "../var/isFunction", 4 "./var/nonce", 5 "./var/rquery", 6 "../ajax" 7 ], function( jQuery, isFunction, nonce, rquery ) { 8 9 "use strict"; 10 11 var oldCallbacks = [], 12 rjsonp = /(=)\?(?=&|$)|\?\?/; 13 14 // Default jsonp settings 15 jQuery.ajaxSetup( { 16 jsonp: "callback", 17 jsonpCallback: function() { 18 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 19 this[ callback ] = true; 20 return callback; 21 } 22 } ); 23 24 // Detect, normalize options and install callbacks for jsonp requests 25 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 26 27 var callbackName, overwritten, responseContainer, 28 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 29 "url" : 30 typeof s.data === "string" && 31 ( s.contentType || "" ) 32 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 33 rjsonp.test( s.data ) && "data" 34 ); 35 36 // Handle iff the expected data type is "jsonp" or we have a parameter to set 37 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 38 39 // Get callback name, remembering preexisting value associated with it 40 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 41 s.jsonpCallback() : 42 s.jsonpCallback; 43 44 // Insert callback into url or form data 45 if ( jsonProp ) { 46 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 47 } else if ( s.jsonp !== false ) { 48 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 49 } 50 51 // Use data converter to retrieve json after script execution 52 s.converters[ "script json" ] = function() { 53 if ( !responseContainer ) { 54 jQuery.error( callbackName + " was not called" ); 55 } 56 return responseContainer[ 0 ]; 57 }; 58 59 // Force json dataType 60 s.dataTypes[ 0 ] = "json"; 61 62 // Install callback 63 overwritten = window[ callbackName ]; 64 window[ callbackName ] = function() { 65 responseContainer = arguments; 66 }; 67 68 // Clean-up function (fires after converters) 69 jqXHR.always( function() { 70 71 // If previous value didn't exist - remove it 72 if ( overwritten === undefined ) { 73 jQuery( window ).removeProp( callbackName ); 74 75 // Otherwise restore preexisting value 76 } else { 77 window[ callbackName ] = overwritten; 78 } 79 80 // Save back as free 81 if ( s[ callbackName ] ) { 82 83 // Make sure that re-using the options doesn't screw things around 84 s.jsonpCallback = originalSettings.jsonpCallback; 85 86 // Save the callback name for future use 87 oldCallbacks.push( callbackName ); 88 } 89 90 // Call if it was a function and we have a response 91 if ( responseContainer && isFunction( overwritten ) ) { 92 overwritten( responseContainer[ 0 ] ); 93 } 94 95 responseContainer = overwritten = undefined; 96 } ); 97 98 // Delegate to script 99 return "script"; 100 } 101 } ); 102 103 } );