You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					223 lines
				
				7.2 KiB
			
		
		
			
		
	
	
					223 lines
				
				7.2 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var utils = require('./../utils');
							 | 
						||
| 
								 | 
							
								var settle = require('./../core/settle');
							 | 
						||
| 
								 | 
							
								var cookies = require('./../helpers/cookies');
							 | 
						||
| 
								 | 
							
								var buildURL = require('./../helpers/buildURL');
							 | 
						||
| 
								 | 
							
								var buildFullPath = require('../core/buildFullPath');
							 | 
						||
| 
								 | 
							
								var parseHeaders = require('./../helpers/parseHeaders');
							 | 
						||
| 
								 | 
							
								var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
							 | 
						||
| 
								 | 
							
								var transitionalDefaults = require('../defaults/transitional');
							 | 
						||
| 
								 | 
							
								var AxiosError = require('../core/AxiosError');
							 | 
						||
| 
								 | 
							
								var CanceledError = require('../cancel/CanceledError');
							 | 
						||
| 
								 | 
							
								var parseProtocol = require('../helpers/parseProtocol');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = function xhrAdapter(config) {
							 | 
						||
| 
								 | 
							
								  return new Promise(function dispatchXhrRequest(resolve, reject) {
							 | 
						||
| 
								 | 
							
								    var requestData = config.data;
							 | 
						||
| 
								 | 
							
								    var requestHeaders = config.headers;
							 | 
						||
| 
								 | 
							
								    var responseType = config.responseType;
							 | 
						||
| 
								 | 
							
								    var onCanceled;
							 | 
						||
| 
								 | 
							
								    function done() {
							 | 
						||
| 
								 | 
							
								      if (config.cancelToken) {
							 | 
						||
| 
								 | 
							
								        config.cancelToken.unsubscribe(onCanceled);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (config.signal) {
							 | 
						||
| 
								 | 
							
								        config.signal.removeEventListener('abort', onCanceled);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (utils.isFormData(requestData) && utils.isStandardBrowserEnv()) {
							 | 
						||
| 
								 | 
							
								      delete requestHeaders['Content-Type']; // Let the browser set it
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var request = new XMLHttpRequest();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // HTTP basic authentication
							 | 
						||
| 
								 | 
							
								    if (config.auth) {
							 | 
						||
| 
								 | 
							
								      var username = config.auth.username || '';
							 | 
						||
| 
								 | 
							
								      var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';
							 | 
						||
| 
								 | 
							
								      requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var 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
							 | 
						||
| 
								 | 
							
								      var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
							 | 
						||
| 
								 | 
							
								      var responseData = !responseType || responseType === 'text' ||  responseType === 'json' ?
							 | 
						||
| 
								 | 
							
								        request.responseText : request.response;
							 | 
						||
| 
								 | 
							
								      var response = {
							 | 
						||
| 
								 | 
							
								        data: responseData,
							 | 
						||
| 
								 | 
							
								        status: request.status,
							 | 
						||
| 
								 | 
							
								        statusText: request.statusText,
							 | 
						||
| 
								 | 
							
								        headers: responseHeaders,
							 | 
						||
| 
								 | 
							
								        config: config,
							 | 
						||
| 
								 | 
							
								        request: 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, request));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Clean up request
							 | 
						||
| 
								 | 
							
								      request = null;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Handle timeout
							 | 
						||
| 
								 | 
							
								    request.ontimeout = function handleTimeout() {
							 | 
						||
| 
								 | 
							
								      var timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
							 | 
						||
| 
								 | 
							
								      var 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 (utils.isStandardBrowserEnv()) {
							 | 
						||
| 
								 | 
							
								      // Add xsrf header
							 | 
						||
| 
								 | 
							
								      var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?
							 | 
						||
| 
								 | 
							
								        cookies.read(config.xsrfCookieName) :
							 | 
						||
| 
								 | 
							
								        undefined;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (xsrfValue) {
							 | 
						||
| 
								 | 
							
								        requestHeaders[config.xsrfHeaderName] = xsrfValue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Add headers to the request
							 | 
						||
| 
								 | 
							
								    if ('setRequestHeader' in request) {
							 | 
						||
| 
								 | 
							
								      utils.forEach(requestHeaders, function setRequestHeader(val, key) {
							 | 
						||
| 
								 | 
							
								        if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
							 | 
						||
| 
								 | 
							
								          // Remove Content-Type if data is undefined
							 | 
						||
| 
								 | 
							
								          delete requestHeaders[key];
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          // Otherwise add header to the request
							 | 
						||
| 
								 | 
							
								          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', config.onDownloadProgress);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Not all browsers support upload events
							 | 
						||
| 
								 | 
							
								    if (typeof config.onUploadProgress === 'function' && request.upload) {
							 | 
						||
| 
								 | 
							
								      request.upload.addEventListener('progress', config.onUploadProgress);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (config.cancelToken || config.signal) {
							 | 
						||
| 
								 | 
							
								      // Handle cancellation
							 | 
						||
| 
								 | 
							
								      // eslint-disable-next-line func-names
							 | 
						||
| 
								 | 
							
								      onCanceled = function(cancel) {
							 | 
						||
| 
								 | 
							
								        if (!request) {
							 | 
						||
| 
								 | 
							
								          return;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
							 | 
						||
| 
								 | 
							
								        request.abort();
							 | 
						||
| 
								 | 
							
								        request = null;
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      config.cancelToken && config.cancelToken.subscribe(onCanceled);
							 | 
						||
| 
								 | 
							
								      if (config.signal) {
							 | 
						||
| 
								 | 
							
								        config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!requestData) {
							 | 
						||
| 
								 | 
							
								      requestData = null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var protocol = parseProtocol(fullPath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (protocol && [ 'http', 'https', 'file' ].indexOf(protocol) === -1) {
							 | 
						||
| 
								 | 
							
								      reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Send the request
							 | 
						||
| 
								 | 
							
								    request.send(requestData);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								};
							 |