axios的简介
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
基本用法
// 发送 POST 请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
实现功能
- Axios实例对象生成
- 如何发起请求(适配器)
- 拦截器
- 取消请求
生成Axios实例对象
// default.jsfunction xhr(config) {
return new Promise((resolve, reject) => { var request = new XMLHttpRequest(); request.open(config.method.toUpperCase(), config.url, true); request.onreadystatechange = function() { var response = { data: request.response, status: request.status, statusText: request.statusText, headers: request.getAllResponseHeaders(), config: config, request: request, }; resolve(response); }; request.send(config.data); });}function http() {}// 根据环境获取适配器function getDefaultAdapter() { var adapter; if (typeof XMLHttpRequest !== "undefined") { // For browsers use XHR adapter adapter = xhr; } else if ( typeof process !== "undefined" && Object.prototype.toString.call(process) === "[object process]" ) { // For node use HTTP adapter adapter = http; } return adapter;}// 默认值const defaults = { // 适配器 adapter: getDefaultAdapter(), method: "get",};export default defaults;
// Axios.jsfunction dispatchRequest(config) { var adapter = config.adapter || defaults.adapter; adapter(config).then(response => { console.log(response) }) }function Axios(instanceConfig) { this.defaults = instanceConfig; this.interceptors = { request: {}, response: {}, };}Axios.prototype.request = function(config) { config = { ...this.defaults, ...config }; const promise = dispatchRequest(config); return promise};
// axios.jsvar axios = createInstance(defaults);
在axios中传入defaults值,其他有适配器adapter,通过适配器采用不同的请求方法,此处只实现了浏览器中的请求方法xhr。axios是基于Promise的,所以xhr中返回的是一个promise对象,将在dispatchRequest中调用then返回
拦截器
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
上面是拦截器的用法,我们在Axios构造函数中声明了一个interceptors对象,interceptors对象有request和response两个属性,分别代表请求拦截器实例和响应拦截器实例,拦截器实例中有handlers数组,当调用use方法,往里面push拦截器方法,因为是promise,所以需要添加两个表示成功和失败的回调,request方法中执行拦截器。
请求拦截器 handlers中为[1,2],requestInterceptorChain中使用unshift方法变为[2,1]再执行;响应拦截器 handlers中为[1,2],responseInterceptorChain中使用push方法方法变为[1,2]再执行;最终的结果是“请求拦截2, 请求拦截1, 响应拦截1, 响应拦截2“
function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
function InterceptorManager() {
this.handlers = [];
}
InterceptorManager.prototype.use = function(fulfilled, rejected) {
this.handlers.push({fulfilled,rejected});
return this.handlers.length - 1;
};
InterceptorManager.prototype.forEach = function(fn) {
this.handlers.forEach((handler) => {
fn(handler);
});
};
Axios.prototype.request = function(config) {
config = { ...this.defaults, ...config };
let promise;
let requestInterceptorChain = [];
this.interceptors.request.forEach(function(interceptor) {
requestInterceptorChain.unshift(interceptor.fulfilled,interceptor.rejected);
});
var responseInterceptorChain = [];
this.interceptors.response.forEach(function(interceptor) {
responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);
});
var newConfig = config;
while (requestInterceptorChain.length) {
var onFulfilled = requestInterceptorChain.shift();
var onRejected = requestInterceptorChain.shift();
newConfig = onFulfilled(newConfig);
break;
}
}
promise = dispatchRequest(newConfig);
while (responseInterceptorChain.length) {
promise = promise.then(
responseInterceptorChain.shift(),
responseInterceptorChain.shift()
);
}
return promise;
};