| 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(); |
| flushDownload && flushDownload(); |
|
|
| _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); |
|
|
| |
| request.timeout = _config.timeout; |
|
|
| function onloadend() { |
| if (!request) { |
| return; |
| } |
| |
| 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 |
| ); |
|
|
| |
| request = null; |
| } |
|
|
| if ('onloadend' in request) { |
| |
| request.onloadend = onloadend; |
| } else { |
| |
| request.onreadystatechange = function handleLoad() { |
| if (!request || request.readyState !== 4) { |
| return; |
| } |
|
|
| |
| |
| |
| |
| if ( |
| request.status === 0 && |
| !(request.responseURL && request.responseURL.indexOf('file:') === 0) |
| ) { |
| return; |
| } |
| |
| |
| setTimeout(onloadend); |
| }; |
| } |
|
|
| |
| request.onabort = function handleAbort() { |
| if (!request) { |
| return; |
| } |
|
|
| reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request)); |
|
|
| |
| request = null; |
| }; |
|
|
| |
| request.onerror = function handleError(event) { |
| |
| |
| |
| const msg = event && event.message ? event.message : 'Network Error'; |
| const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); |
| |
| err.event = event || null; |
| reject(err); |
| request = null; |
| }; |
|
|
| |
| 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 |
| ) |
| ); |
|
|
| |
| request = null; |
| }; |
|
|
| |
| requestData === undefined && requestHeaders.setContentType(null); |
|
|
| |
| if ('setRequestHeader' in request) { |
| utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { |
| request.setRequestHeader(key, val); |
| }); |
| } |
|
|
| |
| if (!utils.isUndefined(_config.withCredentials)) { |
| request.withCredentials = !!_config.withCredentials; |
| } |
|
|
| |
| if (responseType && responseType !== 'json') { |
| request.responseType = _config.responseType; |
| } |
|
|
| |
| if (onDownloadProgress) { |
| [downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true); |
| request.addEventListener('progress', downloadThrottled); |
| } |
|
|
| |
| if (onUploadProgress && request.upload) { |
| [uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress); |
|
|
| request.upload.addEventListener('progress', uploadThrottled); |
|
|
| request.upload.addEventListener('loadend', flushUpload); |
| } |
|
|
| if (_config.cancelToken || _config.signal) { |
| |
| |
| 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; |
| } |
|
|
| |
| request.send(requestData || null); |
| }); |
| }; |
|
|