| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 | import utils from './../utils.js';import settle from './../core/settle.js';import transitionalDefaults from '../defaults/transitional.js';import AxiosError from '../core/AxiosError.js';import CanceledError from '../cancel/CanceledError.js';import parseProtocol from '../helpers/parseProtocol.js';import platform from '../platform/index.js';import AxiosHeaders from '../core/AxiosHeaders.js';import {progressEventReducer} from '../helpers/progressEventReducer.js';import resolveConfig from "../helpers/resolveConfig.js";const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';export default isXHRAdapterSupported && function (config) {  return new Promise(function dispatchXhrRequest(resolve, reject) {    const _config = resolveConfig(config);    let requestData = _config.data;    const requestHeaders = AxiosHeaders.from(_config.headers).normalize();    let {responseType, onUploadProgress, onDownloadProgress} = _config;    let onCanceled;    let uploadThrottled, downloadThrottled;    let flushUpload, flushDownload;    function done() {      flushUpload && flushUpload(); // flush events      flushDownload && flushDownload(); // flush events      _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);      _config.signal && _config.signal.removeEventListener('abort', onCanceled);    }    let request = new XMLHttpRequest();    request.open(_config.method.toUpperCase(), _config.url, true);    // Set the request timeout in MS    request.timeout = _config.timeout;    function onloadend() {      if (!request) {        return;      }      // Prepare the response      const responseHeaders = AxiosHeaders.from(        'getAllResponseHeaders' in request && request.getAllResponseHeaders()      );      const responseData = !responseType || responseType === 'text' || responseType === 'json' ?        request.responseText : request.response;      const response = {        data: responseData,        status: request.status,        statusText: request.statusText,        headers: responseHeaders,        config,        request      };      settle(function _resolve(value) {        resolve(value);        done();      }, function _reject(err) {        reject(err);        done();      }, response);      // Clean up request      request = null;    }    if ('onloadend' in request) {      // Use onloadend if available      request.onloadend = onloadend;    } else {      // Listen for ready state to emulate onloadend      request.onreadystatechange = function handleLoad() {        if (!request || request.readyState !== 4) {          return;        }        // The request errored out and we didn't get a response, this will be        // handled by onerror instead        // With one exception: request that using file: protocol, most browsers        // will return status as 0 even though it's a successful request        if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {          return;        }        // readystate handler is calling before onerror or ontimeout handlers,        // so we should call onloadend on the next 'tick'        setTimeout(onloadend);      };    }    // Handle browser request cancellation (as opposed to a manual cancellation)    request.onabort = function handleAbort() {      if (!request) {        return;      }      reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));      // Clean up request      request = null;    };    // Handle low level network errors    request.onerror = function handleError() {      // Real errors are hidden from us by the browser      // onerror should only fire if it's a network error      reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));      // Clean up request      request = null;    };    // Handle timeout    request.ontimeout = function handleTimeout() {      let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';      const transitional = _config.transitional || transitionalDefaults;      if (_config.timeoutErrorMessage) {        timeoutErrorMessage = _config.timeoutErrorMessage;      }      reject(new AxiosError(        timeoutErrorMessage,        transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,        config,        request));      // Clean up request      request = null;    };    // Remove Content-Type if data is undefined    requestData === undefined && requestHeaders.setContentType(null);    // Add headers to the request    if ('setRequestHeader' in request) {      utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {        request.setRequestHeader(key, val);      });    }    // Add withCredentials to request if needed    if (!utils.isUndefined(_config.withCredentials)) {      request.withCredentials = !!_config.withCredentials;    }    // Add responseType to request if needed    if (responseType && responseType !== 'json') {      request.responseType = _config.responseType;    }    // Handle progress if needed    if (onDownloadProgress) {      ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));      request.addEventListener('progress', downloadThrottled);    }    // Not all browsers support upload events    if (onUploadProgress && request.upload) {      ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));      request.upload.addEventListener('progress', uploadThrottled);      request.upload.addEventListener('loadend', flushUpload);    }    if (_config.cancelToken || _config.signal) {      // Handle cancellation      // eslint-disable-next-line func-names      onCanceled = cancel => {        if (!request) {          return;        }        reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);        request.abort();        request = null;      };      _config.cancelToken && _config.cancelToken.subscribe(onCanceled);      if (_config.signal) {        _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);      }    }    const protocol = parseProtocol(_config.url);    if (protocol && platform.protocols.indexOf(protocol) === -1) {      reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));      return;    }    // Send the request    request.send(requestData || null);  });}
 |