axios源码阅读
1.为什么 axios 既可以当函数调用,也可以当对象使用,比如axios({})、axios.get?
axios本质是函数function,赋值了一些别名方法,比如get、post方法,可被调用,最终调用的还是Axios.prototype.request函数;2.简述 axios 调用流程?
调用的Axios.prototype.request方法,最终返回的是promise链式调用,实际请求是在dispatchRequest中派发的。3.有用过拦截器吗?原理是怎样的?
使用过,用axios.interceptors.request.use添加请求成功和失败拦截器函数,用axios.interceptors.response.use添加响应成功和失败拦截器函数。在Axios.prototype.request函数组成promise链式调用时,Interceptors.protype.forEach遍历请求和响应拦截器添加到真正发送请求dispatchRequest的两端,从而做到请求前拦截和响应后拦截。拦截器也支持用Interceptors.protype.eject方法移除。-
4.有使用axios的取消功能吗?是怎么实现的?
source.cancel()
resolvePromise(token.reason);
config.cancelToken.promise.then(function onCanceled(cancel) {})通过传递config配置cancelToken的形式,来取消的。判断有传cancelToken,在promise链式调用的dispatchRequest抛出错误,在adapter中request.abort()取消请求,使promise走向rejected,被用户捕获取消信息
5.为什么支持浏览器中发送请求也支持node发送请求?
axios.defaults.adapter默认配置中根据环境判断是浏览器还是node环境,使用对应的适配器。适配器支持自定义adapter6.axios问题,以及相关对比?umi-request、fetch、ajax?
axios简单封装
import axios from 'axios';
import store from '@/store';
import Cookies from 'js-cookie';
import { COOKIES_CONSTANTS } from '@/constants';
import i18n from '@/lang';
import { Message } from 'element-ui';
import router from '@/router';
import { IDS_API } from '@/api';
axios.defaults.timeout = 600000;
axios.interceptors.request.use(
config => {
const token = store.state.account.token || Cookies.get(COOKIES_CONSTANTS.TOKEN);
// 添加请求头
config.headers = {
...config.headers,
Authorization: token,
appCode: process.env.VUE_APP_APP_CODE
};
// console.log(config);
// 指定语言
const acceptLanguage = {
'en': 'en-us,en;q=0.5'
}[i18n.locale];
if (acceptLanguage) {
config.headers['Accept-Language'] = acceptLanguage; // 请求的header中带上语言
}
return config;
},
err => {
return Promise.reject(err);
}
);
axios.interceptors.response.use(
response => response,
// 异常处理
error => {
const { response = {} } = error;
const { status, data = {} } = response;
const { msg } = data;
Message.error({
400: {
message: 'Session timeout, please login again',
onClose: () => IDS_API.login(router.history.current.fullPath) // 指定登出的path,重新登录后可以回到path
},
401: 'Authorization failed',
404: 'Resource not found',
500: 'Server error'
}[status] || msg || 'System error!');
return response ? Promise.reject(data) : Promise.reject(error);
}
);
const request = (method, url, params = {}) => {
return new Promise((resolve, reject) => {
axios[method](url, params).then(response => resolve(response.data)).catch(error => reject(error));
});
};
export default {
axios,
get (url, params) {
return request('get', url, { params });
},
post (url, params) {
return request('post', url, params);
},
patch (url, params) {
return request('patch', url, params);
},
put (url, params) {
return request('put', url, params);
},
delete (url, params) {
return request('delete', url, { params });
}
};