vue下axios拦截器token刷新机制的实例代码
//创建http.js文件,以下是具体代码:
//引入安装的axios插件
importaxiosfrom'axios'
importrouterfrom'@/router';
importVuefrom'vue'
constqs=require("qs");
let_this=newVue();
letisLock=false;
letrefreshSubscribers=[];
//判断token是否过期
functionisTokenExpired(token){
letexpires_time=JSON.parse(token).expires_time;
letcurentTime=newDate().getTime();
if(curentTime>=expires_time){
returntrue;
}else{
returnfalse;
}
}
//获取Token对象
functiongetToken(){
returnlocalStorage.getItem("token");
}
//push所有请求到数组中
functionsubscribeTokenRefresh(cb){
refreshSubscribers.push(cb)
}
//刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)
functiononRrefreshed(token){
refreshSubscribers.map(cb=>cb(token))
}
//刷新token
functionrefreshToken(config,token,resolve,reject){
letdata={refresh_token:JSON.parse(token).refresh_token};
axios({
method:"post",
url:"xxxxxx/refreshToken",//刷新token的接口
headers:{
"Content-Type":"application/x-www-form-urlencoded",
"Authorization":"Basicb3JkZXItc2VydmVyOjEyMzQ1Ng=="
},
data:qs.stringify(data)
}).then(res=>{
isLock=false;//释放锁
if(res.data.code===101){
_this.$message.error('登录状态已失效,请重新登录。');
localStorage.removeItem("token");
router.push({
path:"/login"
});
return;
}
letexpires_time=newDate().getTime()+parseInt(res.data.data.expires_in*0.8)*1000;
lettoken=JSON.parse(localStorage.getItem("token"));
token.expires_time=expires_time;
token.access_token=res.data.data.access_token;
localStorage.setItem("token",JSON.stringify(token));
config.headers.Authorization='Bearer'+res.data.data.access_token;
resolve(config);
//执行数组里的函数,重新发起被挂起的请求
onRrefreshed(res.data.data.access_token)
//清空数组中保存的请求
refreshSubscribers=[]
}).catch(err=>{
returnerr;
});
}
functionrequest(newOptions,resolve,reject){
axios({
method:newOptions.method,
url:newOptions.url,
data:newOptions.type=="form"?qs.stringify(newOptions.data):newOptions.data,
headers:newOptions.headers
}).then(res=>{
if(res.status==200){
//这里我们只需要获取返回的data中的数据即可
resolve(res.data);
}else{
reject(res.data);
}
}).catch(err=>{
reject(err);
_this.$message.error('服务异常!');
})
}
axios.interceptors.request.use(
config=>{
lettoken=getToken();
if(token){
//判断token是否过期,如果过期请求刷新token
if(isTokenExpired(token)){
//判断当前是否正在请求刷新token
if(!isLock){
isLock=true;//isLock设置true,锁住防止死循环。
//使用Promise等待刷新完成返回配置信息
letrefresh=newPromise((resolve,reject)=>{
refreshToken(config,token,resolve,reject);
})
returnrefresh;
}else{
//判断当前url是否是刷新token的请求地址,如果是直接下一步。
if(config.url.indexOf('/logined/refreshToken')===-1){
//把请求(token)=>{....}都push到一个数组中
letretry=newPromise((resolve,reject)=>{
//(token)=>{...}这个函数就是回调函数
subscribeTokenRefresh((token)=>{
config.headers.Authorization='Bearer'+token
//将请求挂起
resolve(config)
})
})
returnretry
}else{
returnconfig;
}
}
}else{
returnconfig;
}
}else{
returnconfig;
}
},error=>{
returnPromise.reject(error);
});
consthttp=options=>{
returnnewPromise((resolve,reject)=>{
constdefaultOptions={
type:"json"
};
constnewOptions={
...defaultOptions,
...options
};
//headers默认传递json格式数据,这里也可以设置token,每次调用都会携带
if(localStorage.getItem("token")){
newOptions.headers={
//'Authorization':'Basicb3JkZXItc2VydmVyOjEyMzQ1Ng==',
'content-Type':newOptions.type=='form'?'application/x-www-form-urlencoded;charset=UTF-8':'application/json;charset=UTF-8',
'Authorization':'Bearer'+JSON.parse(localStorage.getItem("token")).access_token,
...newOptions.headers
};
}else{
newOptions.headers={
'content-Type':newOptions.type=='form'?'application/x-www-form-urlencoded;charset=UTF-8':'application/json;charset=UTF-8',
...newOptions.headers
};
}
request(newOptions,resolve,reject);
})
};
//设置请求超时
axios.defaults.timeout=30000
exportdefaulthttp
//在main.js下面挂载http.js文件
importhttpfrom'@/utils/http.js';
Vue.prototype.http=http;
//登录保存token信息接口
this.http({
method:"post",
url:"/xxxxx/user",
type:"form",
headers:{Authorization:"Basicb3JkZXItc2VydmVyOjEyMzQ1Ng=="},
data:{}
}).then(function(res){
letexpires_time=
newDate().getTime()+
parseInt(res.data.token.expires_in*0.8)*1000;
lettoken=res.data.token;
token.expires_time=expires_time;
localStorage.setItem("token",JSON.stringify(token));
}).catch(function(err){
console.log(err);
});
//退出清空token
this.http({
method:"get",
url:"/xxxxx/logout",
data:{}
}).then(function(res){
localStorage.removeItem("token");
}).catch(function(err){
console.log(err);
});
总结
以上所述是小编给大家介绍的vue下axios拦截器token刷新机制的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。