1.什么是axios?
Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。
Axios主要用于想后台发起请求,还有在请求中做更多可控功能。
2.特性
- 从浏览器中创建XMLHttpRequest
- 从node.js创建http请求
- 支持Promise API
- 拦截请求和相应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF(跨站请求伪造)
3.安装
使用npm
npm install axios
4.案例
执行get请求
//为给定ID的user创建请求
//写法1
axios.get('/user?ID=1234')
.then(function(response){
console.log(response)
}).catch(function(error){
console.log(error)
})
//写法2
axios.get('/user',{params:{ID:123}})
.then(function(response){
console.log(response)
}).catch(function(error){
console.log(error)
})
执行post请求
axios.post('/user',{firstName:'aa',lastName:'bb'})
.then(function(response){
console.log(response)
}).catch(function(error){
console.log(error)
})
执行多个并发请求
function getUserAccount(){
return axios.get('/user/123')
}
function getUserPermissions(){
return axios.get('/user/123/Permissions')
}
axios.all([getUserAccount(),getUserPermissions()])
.then(axios.spread(function(acct,perms){
//两个请求现在都执行完成
})
).catch(function(error){
console.log(error)
})
5 axios API
可以通过想 axios传递相关配置来创建请求
axios(config)
//发送post请求
axios({
method:'post',
url:'/user/123',
data:{
firstName:'aa',
lastName:'bb'
}
})
// 获取远端图片
axios({
method:'get',
url:'http://bit.ly/3sdfs',
responseType:'stream',
})
.then(function(response){
response.data.pipe(fs.createWriteStream('ada_loveace.jpg'))
})
axios(url[,config])
axios('/user/12234')
6.创建实例 拦截器
创建实例
可以使用自定义配置新建一个axios实例
axios.create([config])
const instance=axios.create({
baseURL:'https://some-domain.com/api',
timeout:1000,
headers:{'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'}
})
拦截器
在请求或响应被then或者catch处理前拦截它们
//添加请求拦截器
instance.interceptors.request.use(function(config){
//在发送请求之前做什么
return config;
},function(error){
//对请求错误做些什么
return Promise.reject(error)
})
//添加响应拦截器
instance.interceptors.reponse.use(function(response){
//对响应数据做点什么
return response ;
},function(error){
// 对响应错误做点什么
return Promise.reject(error)
}
)
拦截器流程:
😇 写到此处终于明白项目中request.js文件的意思 以及方法的调用 传参为什么要那样写了 image.png
😇 具体分析
import axios from 'axios';
import { Message, MessageBox } from 'element-ui';
import store from '@/store';
import router from '@/router';
import { getToken } from '@/utils/auth';
// 是否正在刷新的标记
let isRefreshing = false;
// 重试队列,每一项将是一个待执行的函数形式
let requests = [];
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
withCredentials: true, // send cookies when cross-domain requests
timeout: 60000 // request timeout
});
service.setToken = (token) => {
service.defaults.headers['Authorization'] = 'Bearer ' + token;
window.localStorage.setItem('Admin-Token', token);
};
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
// let each request carry token --['X-Token'] as a custom key.
// please modify it according to the actual situation.
config.headers['Authorization'] = 'Bearer ' + getToken();
/* config.headers['Devjira'] = window.localStorage.getItem('devjira')*/
}
if (['post', 'put', 'delete'].includes(config.method) && typeof config.data === 'object') {
config.data = Object.keys(config.data).map(key => `${key}=${config.data[key]}`).join('&');
config.data = encodeURI(config.data); // 解决参数中包含特殊字符无法保存的问题
config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
}
return config;
},
error => {
// do something with request error
console.log(error); // for debug
return Promise.reject(error);
}
);
/* 重新获取新的token*/
function refreshToken() {
// service是当前request.js中已创建的axios实例
return axios({
method: 'post',
url: 'api-auth/oauth/token',
params: {
client_id: 'webApp',
client_secret: 'webApp',
refresh_token: localStorage.getItem('refresh_token'),
grant_type: 'refresh_token'
}
}).then(res => res);
}
// response interceptor
service.interceptors.response.use(
/**
* If you want to get information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code.
*/
response => {
// const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (response.status !== 200) {
Message({
message: response.message || 'error',
type: 'error',
duration: 60 * 1000,
showClose: true
});
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (response.status === 50008 || response.status === 50012 || response.status === 50014) {
// to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload();
});
});
}
return Promise.reject(response.message || 'error');
} else {
return response.data;
}
},
error => {
let message = error.message;
if (error.response && error.response.data && error.response.data['resp_code']) { // 登录提示
message = error.response.data['rsp_msg'] || error.response.data['resp_msg'];
}
console.log('err' + error); // for debug
if (error.response && error.response.data && error.response.data['resp_code'] && error.response.data['resp_msg']) {
if (error.response.data['resp_code'] === '401' && error.response.data['resp_msg'].startsWith('Invalid access token')) {
/* 401超时*/
const config = error.response.config;
if (!isRefreshing) {
isRefreshing = true;
return refreshToken().then(res => {
const token = res.data.access_token;
service.setToken(token);
config.headers['Authorization'] = 'Bearer ' + token;
config.baseURL = '';
// 已经刷新了token,将所有队列中的请求进行重试
requests.forEach(cb => cb(token));
requests = [];
return service(config); // 重新执行当前的接口
}).catch(res => {
const message = '会话超时,请重新登录';
store.dispatch('user/logout');
router.push({ path: `/login?redirect=${message}`, params: { errorMessage: message }});
}).finally(() => {
isRefreshing = false;
});
} else {
// 正在刷新token,将返回一个未执行resolve的promise
return new Promise((resolve) => {
// 将resolve放进队列,用一个函数形式来保存,等token刷新后直接执行
requests.push((token) => {
config.baseURL = '';
config.headers['Authorization'] = 'Bearer ' + token;
resolve(service(config));
});
});
}
} else {
Message({
dangerouslyUseHTMLString: true,
message: error.response.data['resp_msg'],
type: 'error',
duration: 5 * 1000,
showClose: true
});
}
} else {
Message({
dangerouslyUseHTMLString: true,
message: `${message}${error.response && error.response.data && error.response.data.message ? '
' + error.response.data.message : ''}`,
type: 'error',
duration: 5 * 1000,
showClose: true
});
}
return Promise.reject(error);
}
);
export default service;
网友评论