智慧水务管理系统 - 精河县供水工程综合管理平台

xhr.js 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import utils from '../utils.js';
  2. import settle from '../core/settle.js';
  3. import transitionalDefaults from '../defaults/transitional.js';
  4. import AxiosError from '../core/AxiosError.js';
  5. import CanceledError from '../cancel/CanceledError.js';
  6. import parseProtocol from '../helpers/parseProtocol.js';
  7. import platform from '../platform/index.js';
  8. import AxiosHeaders from '../core/AxiosHeaders.js';
  9. import { progressEventReducer } from '../helpers/progressEventReducer.js';
  10. import resolveConfig from '../helpers/resolveConfig.js';
  11. import { toByteStringHeaderObject } from '../helpers/sanitizeHeaderValue.js';
  12. const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';
  13. export default isXHRAdapterSupported &&
  14. function (config) {
  15. return new Promise(function dispatchXhrRequest(resolve, reject) {
  16. const _config = resolveConfig(config);
  17. let requestData = _config.data;
  18. const requestHeaders = AxiosHeaders.from(_config.headers).normalize();
  19. let { responseType, onUploadProgress, onDownloadProgress } = _config;
  20. let onCanceled;
  21. let uploadThrottled, downloadThrottled;
  22. let flushUpload, flushDownload;
  23. function done() {
  24. flushUpload && flushUpload(); // flush events
  25. flushDownload && flushDownload(); // flush events
  26. _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);
  27. _config.signal && _config.signal.removeEventListener('abort', onCanceled);
  28. }
  29. let request = new XMLHttpRequest();
  30. request.open(_config.method.toUpperCase(), _config.url, true);
  31. // Set the request timeout in MS
  32. request.timeout = _config.timeout;
  33. function onloadend() {
  34. if (!request) {
  35. return;
  36. }
  37. // Prepare the response
  38. const responseHeaders = AxiosHeaders.from(
  39. 'getAllResponseHeaders' in request && request.getAllResponseHeaders()
  40. );
  41. const responseData =
  42. !responseType || responseType === 'text' || responseType === 'json'
  43. ? request.responseText
  44. : request.response;
  45. const response = {
  46. data: responseData,
  47. status: request.status,
  48. statusText: request.statusText,
  49. headers: responseHeaders,
  50. config,
  51. request,
  52. };
  53. settle(
  54. function _resolve(value) {
  55. resolve(value);
  56. done();
  57. },
  58. function _reject(err) {
  59. reject(err);
  60. done();
  61. },
  62. response
  63. );
  64. // Clean up request
  65. request = null;
  66. }
  67. if ('onloadend' in request) {
  68. // Use onloadend if available
  69. request.onloadend = onloadend;
  70. } else {
  71. // Listen for ready state to emulate onloadend
  72. request.onreadystatechange = function handleLoad() {
  73. if (!request || request.readyState !== 4) {
  74. return;
  75. }
  76. // The request errored out and we didn't get a response, this will be
  77. // handled by onerror instead
  78. // With one exception: request that using file: protocol, most browsers
  79. // will return status as 0 even though it's a successful request
  80. if (
  81. request.status === 0 &&
  82. !(request.responseURL && request.responseURL.startsWith('file:'))
  83. ) {
  84. return;
  85. }
  86. // readystate handler is calling before onerror or ontimeout handlers,
  87. // so we should call onloadend on the next 'tick'
  88. setTimeout(onloadend);
  89. };
  90. }
  91. // Handle browser request cancellation (as opposed to a manual cancellation)
  92. request.onabort = function handleAbort() {
  93. if (!request) {
  94. return;
  95. }
  96. reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));
  97. done();
  98. // Clean up request
  99. request = null;
  100. };
  101. // Handle low level network errors
  102. request.onerror = function handleError(event) {
  103. // Browsers deliver a ProgressEvent in XHR onerror
  104. // (message may be empty; when present, surface it)
  105. // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event
  106. const msg = event && event.message ? event.message : 'Network Error';
  107. const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);
  108. // attach the underlying event for consumers who want details
  109. err.event = event || null;
  110. reject(err);
  111. done();
  112. request = null;
  113. };
  114. // Handle timeout
  115. request.ontimeout = function handleTimeout() {
  116. let timeoutErrorMessage = _config.timeout
  117. ? 'timeout of ' + _config.timeout + 'ms exceeded'
  118. : 'timeout exceeded';
  119. const transitional = _config.transitional || transitionalDefaults;
  120. if (_config.timeoutErrorMessage) {
  121. timeoutErrorMessage = _config.timeoutErrorMessage;
  122. }
  123. reject(
  124. new AxiosError(
  125. timeoutErrorMessage,
  126. transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
  127. config,
  128. request
  129. )
  130. );
  131. done();
  132. // Clean up request
  133. request = null;
  134. };
  135. // Remove Content-Type if data is undefined
  136. requestData === undefined && requestHeaders.setContentType(null);
  137. // Add headers to the request
  138. if ('setRequestHeader' in request) {
  139. utils.forEach(toByteStringHeaderObject(requestHeaders), function setRequestHeader(val, key) {
  140. request.setRequestHeader(key, val);
  141. });
  142. }
  143. // Add withCredentials to request if needed
  144. if (!utils.isUndefined(_config.withCredentials)) {
  145. request.withCredentials = !!_config.withCredentials;
  146. }
  147. // Add responseType to request if needed
  148. if (responseType && responseType !== 'json') {
  149. request.responseType = _config.responseType;
  150. }
  151. // Handle progress if needed
  152. if (onDownloadProgress) {
  153. [downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true);
  154. request.addEventListener('progress', downloadThrottled);
  155. }
  156. // Not all browsers support upload events
  157. if (onUploadProgress && request.upload) {
  158. [uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress);
  159. request.upload.addEventListener('progress', uploadThrottled);
  160. request.upload.addEventListener('loadend', flushUpload);
  161. }
  162. if (_config.cancelToken || _config.signal) {
  163. // Handle cancellation
  164. // eslint-disable-next-line func-names
  165. onCanceled = (cancel) => {
  166. if (!request) {
  167. return;
  168. }
  169. reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);
  170. request.abort();
  171. done();
  172. request = null;
  173. };
  174. _config.cancelToken && _config.cancelToken.subscribe(onCanceled);
  175. if (_config.signal) {
  176. _config.signal.aborted
  177. ? onCanceled()
  178. : _config.signal.addEventListener('abort', onCanceled);
  179. }
  180. }
  181. const protocol = parseProtocol(_config.url);
  182. if (protocol && !platform.protocols.includes(protocol)) {
  183. reject(
  184. new AxiosError(
  185. 'Unsupported protocol ' + protocol + ':',
  186. AxiosError.ERR_BAD_REQUEST,
  187. config
  188. )
  189. );
  190. return;
  191. }
  192. // Send the request
  193. request.send(requestData || null);
  194. });
  195. };