UNPKG

axios

Version:

Promise based HTTP client for the browser and node.js

116 lines (97 loc) • 3.6 kB
'use strict'; import transformData from './transformData.js'; import isCancel from '../cancel/isCancel.js'; import defaults from '../defaults/index.js'; import CanceledError from '../cancel/CanceledError.js'; import AxiosHeaders from '../core/AxiosHeaders.js'; import adapters from '../adapters/adapters.js'; import utils from '../utils.js'; /** * Throws a `CanceledError` if cancellation has been requested. * * @param {Object} config The config that is to be used for the request * * @returns {void} */ function throwIfCancellationRequested(config) { if (config.cancelToken) { config.cancelToken.throwIfRequested(); } if (config.signal && config.signal.aborted) { throw new CanceledError(null, config); } } /** * Milliseconds elapsed since `start`, floored at zero. * * Wall-clock, to match the rest of the codebase (speedometer, throttle, * AxiosTransformStream). A backwards clock adjustment mid-request would * otherwise produce a negative duration, so the result is clamped. * * @param {number} start Timestamp from `Date.now()` * * @returns {number} Non-negative elapsed milliseconds */ function elapsedSince(start) { return Math.max(0, Date.now() - start); } /** * Dispatch a request to the server using the configured adapter. * * @param {object} config The config that is to be used for the request * * @returns {Promise} The Promise to be fulfilled */ export default function dispatchRequest(_config) { // Interceptors may replace the merged config with an ordinary object. Flatten // it at the dispatch boundary so shared prototype members cannot become // request behavior, while preserving intentional template/class members. const config = utils.toSafeFlatObject(_config); throwIfCancellationRequested(config); config.headers = AxiosHeaders.from(utils.getSafeProp(config, 'headers')); // Transform request data config.data = transformData.call(config, config.transformRequest); if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { config.headers.setContentType('application/x-www-form-urlencoded', false); } const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config); const start = Date.now(); return adapter(config).then( function onAdapterResolution(response) { throwIfCancellationRequested(config); response.duration = elapsedSince(start); // Expose the current response on config so that transformResponse can // attach it to any AxiosError it throws (e.g. on JSON parse failure). // We clean it up afterwards to avoid polluting the config object. config.response = response; try { response.data = transformData.call(config, config.transformResponse, response); } finally { delete config.response; } response.headers = AxiosHeaders.from(response.headers); return response; }, function onAdapterRejection(reason) { if (!isCancel(reason)) { throwIfCancellationRequested(config); // Transform response data if (reason && reason.response) { reason.response.duration = elapsedSince(start); config.response = reason.response; try { reason.response.data = transformData.call( config, config.transformResponse, reason.response ); } finally { delete config.response; } reason.response.headers = AxiosHeaders.from(reason.response.headers); } } return Promise.reject(reason); } ); }