説明なし

xhr.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. define( [
  2. "../core",
  3. "../var/support",
  4. "../ajax"
  5. ], function( jQuery, support ) {
  6. "use strict";
  7. jQuery.ajaxSettings.xhr = function() {
  8. try {
  9. return new window.XMLHttpRequest();
  10. } catch ( e ) {}
  11. };
  12. var xhrSuccessStatus = {
  13. // File protocol always yields status code 0, assume 200
  14. 0: 200,
  15. // Support: IE <=9 only
  16. // #1450: sometimes IE returns 1223 when it should be 204
  17. 1223: 204
  18. },
  19. xhrSupported = jQuery.ajaxSettings.xhr();
  20. support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  21. support.ajax = xhrSupported = !!xhrSupported;
  22. jQuery.ajaxTransport( function( options ) {
  23. var callback, errorCallback;
  24. // Cross domain only allowed if supported through XMLHttpRequest
  25. if ( support.cors || xhrSupported && !options.crossDomain ) {
  26. return {
  27. send: function( headers, complete ) {
  28. var i,
  29. xhr = options.xhr();
  30. xhr.open(
  31. options.type,
  32. options.url,
  33. options.async,
  34. options.username,
  35. options.password
  36. );
  37. // Apply custom fields if provided
  38. if ( options.xhrFields ) {
  39. for ( i in options.xhrFields ) {
  40. xhr[ i ] = options.xhrFields[ i ];
  41. }
  42. }
  43. // Override mime type if needed
  44. if ( options.mimeType && xhr.overrideMimeType ) {
  45. xhr.overrideMimeType( options.mimeType );
  46. }
  47. // X-Requested-With header
  48. // For cross-domain requests, seeing as conditions for a preflight are
  49. // akin to a jigsaw puzzle, we simply never set it to be sure.
  50. // (it can always be set on a per-request basis or even using ajaxSetup)
  51. // For same-domain requests, won't change header if already provided.
  52. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
  53. headers[ "X-Requested-With" ] = "XMLHttpRequest";
  54. }
  55. // Set headers
  56. for ( i in headers ) {
  57. xhr.setRequestHeader( i, headers[ i ] );
  58. }
  59. // Callback
  60. callback = function( type ) {
  61. return function() {
  62. if ( callback ) {
  63. callback = errorCallback = xhr.onload =
  64. xhr.onerror = xhr.onabort = xhr.ontimeout =
  65. xhr.onreadystatechange = null;
  66. if ( type === "abort" ) {
  67. xhr.abort();
  68. } else if ( type === "error" ) {
  69. // Support: IE <=9 only
  70. // On a manual native abort, IE9 throws
  71. // errors on any property access that is not readyState
  72. if ( typeof xhr.status !== "number" ) {
  73. complete( 0, "error" );
  74. } else {
  75. complete(
  76. // File: protocol always yields status 0; see #8605, #14207
  77. xhr.status,
  78. xhr.statusText
  79. );
  80. }
  81. } else {
  82. complete(
  83. xhrSuccessStatus[ xhr.status ] || xhr.status,
  84. xhr.statusText,
  85. // Support: IE <=9 only
  86. // IE9 has no XHR2 but throws on binary (trac-11426)
  87. // For XHR2 non-text, let the caller handle it (gh-2498)
  88. ( xhr.responseType || "text" ) !== "text" ||
  89. typeof xhr.responseText !== "string" ?
  90. { binary: xhr.response } :
  91. { text: xhr.responseText },
  92. xhr.getAllResponseHeaders()
  93. );
  94. }
  95. }
  96. };
  97. };
  98. // Listen to events
  99. xhr.onload = callback();
  100. errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
  101. // Support: IE 9 only
  102. // Use onreadystatechange to replace onabort
  103. // to handle uncaught aborts
  104. if ( xhr.onabort !== undefined ) {
  105. xhr.onabort = errorCallback;
  106. } else {
  107. xhr.onreadystatechange = function() {
  108. // Check readyState before timeout as it changes
  109. if ( xhr.readyState === 4 ) {
  110. // Allow onerror to be called first,
  111. // but that will not handle a native abort
  112. // Also, save errorCallback to a variable
  113. // as xhr.onerror cannot be accessed
  114. window.setTimeout( function() {
  115. if ( callback ) {
  116. errorCallback();
  117. }
  118. } );
  119. }
  120. };
  121. }
  122. // Create the abort callback
  123. callback = callback( "abort" );
  124. try {
  125. // Do send the request (this may raise an exception)
  126. xhr.send( options.hasContent && options.data || null );
  127. } catch ( e ) {
  128. // #14683: Only rethrow if this hasn't been notified as an error yet
  129. if ( callback ) {
  130. throw e;
  131. }
  132. }
  133. },
  134. abort: function() {
  135. if ( callback ) {
  136. callback();
  137. }
  138. }
  139. };
  140. }
  141. } );
  142. } );