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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。