今日来看axios发送申请的局部,在axios中被称为适配器,即配置中的adapter属性.
adapter属性有两个值,在浏览器中应用xhr文件, 在node中
在xhr文件中,应用的其实就是ajax, 也就是XMLHttpRequest这个办法.
var request = new XMLHttpRequest();
当中就有咱们很相熟的open办法(request.open), onreadystatechange办法(request.onreadystatechange), onabort办法(request.onabort), 还有onerror, ontimeout等办法.文件增加了一些判断,使得申请更为欠缺.间接上代码,都看的懂
'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 createError = require('../core/createError');module.exports = function xhrAdapter(config) { return new Promise(function dispatchXhrRequest(resolve, reject) { var requestData = config.data; var requestHeaders = config.headers; if (utils.isFormData(requestData)) { delete requestHeaders['Content-Type']; // Let the browser set it 让浏览器来设置 } var request = new XMLHttpRequest(); // HTTP basic authentication http的根底验证 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; // Listen for ready state 监听ready state 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 申请谬误没有失去响应,将会被onerror解决 // With one exception: request that using file: protocol, most browsers // will return status as 0 even though it's a successful request 有一个例外, 大多数浏览器即便申请胜利也会返回状态为0 if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { return; } // Prepare the response 筹备响应 var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; var response = { data: responseData, status: request.status, statusText: request.statusText, headers: responseHeaders, config: config, request: request }; settle(resolve, reject, response); // Clean up request 革除申请 request = null; }; // Handle browser request cancellation (as opposed to a manual cancellation) 解决浏览器申请勾销操作 request.onabort = function handleAbort() { if (!request) { return; } reject(createError('Request aborted', config, 'ECONNABORTED', 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 如果是个网络谬误会触发onerror reject(createError('Network Error', config, null, request)); // Clean up request request = null; }; // Handle timeout 解决超时 request.ontimeout = function handleTimeout() { var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded'; if (config.timeoutErrorMessage) { timeoutErrorMessage = config.timeoutErrorMessage; } reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', 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. 在web worker或者rn中不会 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 如果data是undefined,移除content-type 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 (config.responseType) { try { request.responseType = config.responseType; } catch (e) { // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. if (config.responseType !== 'json') { throw e; } } } // 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); // XMLHttpRequest的upload属性 } if (config.cancelToken) { // Handle cancellation 勾销操作 config.cancelToken.promise.then(function onCanceled(cancel) { if (!request) { return; } request.abort(); reject(cancel); // Clean up request request = null; }); } if (!requestData) { requestData = null; } // Send the request request.send(requestData); });};