| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | 'use strict';import utils from './../utils.js';import settle from './../core/settle.js';import cookies from './../helpers/cookies.js';import buildURL from './../helpers/buildURL.js';import buildFullPath from '../core/buildFullPath.js';import isURLSameOrigin from './../helpers/isURLSameOrigin.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 speedometer from '../helpers/speedometer.js';function progressEventReducer(listener, isDownloadStream) {  let bytesNotified = 0;  const _speedometer = speedometer(50, 250);  return e => {    const loaded = e.loaded;    const total = e.lengthComputable ? e.total : undefined;    const progressBytes = loaded - bytesNotified;    const rate = _speedometer(progressBytes);    const inRange = loaded <= total;    bytesNotified = loaded;    const data = {      loaded,      total,      progress: total ? (loaded / total) : undefined,      bytes: progressBytes,      rate: rate ? rate : undefined,      estimated: rate && total && inRange ? (total - loaded) / rate : undefined,      event: e    };    data[isDownloadStream ? 'download' : 'upload'] = true;    listener(data);  };}const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';export default isXHRAdapterSupported && function (config) {  return new Promise(function dispatchXhrRequest(resolve, reject) {    let requestData = config.data;    const requestHeaders = AxiosHeaders.from(config.headers).normalize();    const responseType = config.responseType;    let onCanceled;    function done() {      if (config.cancelToken) {        config.cancelToken.unsubscribe(onCanceled);      }      if (config.signal) {        config.signal.removeEventListener('abort', onCanceled);      }    }    if (utils.isFormData(requestData) && (platform.isStandardBrowserEnv || platform.isStandardBrowserWebWorkerEnv)) {      requestHeaders.setContentType(false); // Let the browser set it    }    let request = new XMLHttpRequest();    // HTTP basic authentication    if (config.auth) {      const username = config.auth.username || '';      const password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';      requestHeaders.set('Authorization', 'Basic ' + btoa(username + ':' + password));    }    const fullPath = buildFullPath(config.baseURL, config.url);    request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), 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;    };    // Add xsrf header    // This is only done if running in a standard browser environment.    // Specifically not if we're in a web worker, or react-native.    if (platform.isStandardBrowserEnv) {      // Add xsrf header      const xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath))        && config.xsrfCookieName && cookies.read(config.xsrfCookieName);      if (xsrfValue) {        requestHeaders.set(config.xsrfHeaderName, xsrfValue);      }    }    // 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 (typeof config.onDownloadProgress === 'function') {      request.addEventListener('progress', progressEventReducer(config.onDownloadProgress, true));    }    // Not all browsers support upload events    if (typeof config.onUploadProgress === 'function' && request.upload) {      request.upload.addEventListener('progress', progressEventReducer(config.onUploadProgress));    }    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(fullPath);    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);  });}
 |