jsonp.js 2.7 KB

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