**在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御cSRF等,下面是个完整实例...**
```
import axios from 'axios';
import emd5 from 'js-md5';
import cx from './config.js';
const isToken = cx.isToken || false;
const tokenCacheKey = cx.tokenCacheKey;
const tokenSecret = cx.tokenSecret;
const tokenCreate = cx.apiToken;
const tokenRefresh = cx.apiTokenRefresh;
const filterArray = [tokenCreate,tokenRefresh];
const apiConfig = {
baseURL : cx.baseUrl,
timeout : cx.timeOut,
withCredentials : true /* 表示跨域请求时是否需要使用凭证 默认false */
};
let apiQueue = []; /* 请求队列 */
let api = axios.create(apiConfig);
/* 请求拦截器 */
api.interceptors.request.use(
config => {
if(isToken === false){
return config;
}
_pushQueue(config)
let data = _token(config);
return data;
},
error => {
return Promise.reject(error);
}
);
/* 响应拦截器 */
api.interceptors.response.use(
response => {
return _response(response.data);
},
error => {
return Promise.reject(error);
}
);
/**
* 处理拦截器响应
* @param {Object} res
*/
function _response(res){
try{
if(isToken === false){
return res;
}
/* 可以增加其他拓展 */
switch (res.code){
case '10003' || '10004':
return _tokenRefresh().then(res=>{
return _cacheRequest(res)
})
break;
default :
apiQueue = [];
return res;
break;
}
}catch(e){
return Promise.reject(e)
}
}
/* 刷新token */
function _tokenRefresh(){
let token = window.localStorage.getItem(tokenCacheKey),
author = {Authorization : `bearer ${token}`};
return new Promise((resolve,reject)=>{
apiConfig.headers = author;
axios.create(apiConfig).get(tokenRefresh).then(res=>{
if(res.data.code == '200'){
token = res.data.data.refresh_token;
window.localStorage.setItem(tokenCacheKey,token);
if(apiQueue.length == 0){
reject('没有可以执行的方法');
}
resolve(apiQueue[0])
}else{
reject(res.data.msg);
}
}).catch(error=>{
reject(error);
})
});
}
/* 获取token */
function _token(config){
let token = window.localStorage.getItem(tokenCacheKey);
if(token != '' && token != 'undefined' && token !== null){
config.headers.Authorization = `bearer ${token}`
return config;
}else{
let deviceId = uni.getSystemInfoSync().deviceId,
secret = `${deviceId}&${tokenSecret}`;
return axios.get(tokenCreate,{
params : {
mac : deviceId,
secret : emd5(secret)
}
})
.then(response => {
token = response.data.data.token;
window.localStorage.setItem(tokenCacheKey,token);
config.headers.Authorization = `bearer ${token}`
return config;
})
.catch(error => {
return Promise.reject(error);
})
}
}
/* 添加待执行方法进入队列 */
function _pushQueue(config){
if(true === filterArray.includes(config.url)){
return false;
}
apiQueue.push({
url : config.url,
method : config.method,
params : config.params,
data : config.data
});
}
/**
* @param {Object} config
* @description 重新发送队列中的缓存的请求,为避免多余发送,只取第一个且发送成功后清空队列
*/
function _cacheRequest(config){
let request = {url:config.url,method:config.method};
if(config.method == 'get'){
request.params = config.params;
}else if(config.method == 'post'){
request.data = config.data;
}
return api.request(request)
.then(result => {
apiQueue = [];
return Promise.resolve(result);
}).catch(error => {
return Promise.reject(error)
})
}
/**
* @param {String} url
* @param {Array} data
* @description 对外暴露的POST方法
*/
let cxPost = (url,data)=>{
return _cacheRequest({
url : url,
method : 'post',
data : data
});
}
/**
* @param {String} url
* @param {Array} data
* @description 对外暴露的GET方法
*/
let cxGet = (url,data)=>{
return _cacheRequest({
url : url,
method : 'get',
params : data
});
}
export {cxGet,cxPost};
```