vue拦截器刷新登陆页面_vue下axios拦截器token刷新版机制的实例代码

//创建http.js文件,以下是详细代码:

//引入安装的axios插件

import axios from 'axios'

import router from '@/router';

import Vue from 'vue'

const qs = require("qs");

let _this = new Vue();

let isLock = false;

let refreshSubscribers = [];

//判断token是否过期

function isTokenExpired(token) {

let expires_time = JSON.parse(token).expires_time;

let curentTime = new Date().getTime();

if (curentTime >= expires_time) {

return true;

} else {

return false;

}

}

//获取Token对象

function getToken() {

return localStorage.getItem("token");

}

//push所有请求到数组中

function subscribeTokenRefresh(cb) {

refreshSubscribers.push(cb)

}

//刷新版请求(refreshSubscribers数组中的请求得到新版的token之后会自执行,用新版的token去请求数据)

function onRrefreshed(token) {

refreshSubscribers.map(cb => cb(token))

}

//刷新版token

function refreshToken(config, token, resolve, reject) {

let data = { refresh_token: JSON.parse(token).refresh_token };

axios({

method: "post",

url: "xxxxxx/refreshToken",//刷新版token的接口

headers: {

"Content-Type": "application/x-www-form-urlencoded",

"Authorization": "Basic b3JkZXItc2VydmVyOjEyMzQ1Ng=="

},

data: qs.stringify(data)

}).then(res => {

isLock = false;//释放锁

if (res.data.code === 101) {

_this.$message.error('登陆状态已失效,请重新版登陆。');

localStorage.removeItem("token");

router.push({

path: "/login"

});

return;

}

let expires_time = new Date().getTime() + parseInt(res.data.data.expires_in * 0.8) * 1000;

let token = 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 => {

return err;

});

}

function request(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 => {

let token = getToken();

if (token) {

//判断token是否过期,如果过期请求刷新版token

if (isTokenExpired(token)) {

//判断当前是否正在请求刷新版token

if (!isLock) {

isLock = true;//isLock设置true,锁住防止死循环。

//使用Promise等待刷新版完成返回配置信息

let refresh = new Promise((resolve, reject) => {

refreshToken(config, token, resolve, reject);

})

return refresh;

} else {

//判断当前url是否是刷新版token的请求地址,如果是直接下一步。

if (config.url.indexOf('/logined/refreshToken') === -1) {

//把请求(token)=>{....}都push到一个数组中

let retry = new Promise((resolve, reject) => {

//(token) => {...}这个函数就是回调函数

subscribeTokenRefresh((token) => {

config.headers.Authorization = 'Bearer ' + token

//将请求挂起

resolve(config)

})

})

return retry

} else {

return config;

}

}

} else {

return config;

}

} else {

return config;

}

}, error => {

return Promise.reject(error);

});

const http = options => {

return new Promise((resolve, reject) => {

const defaultOptions = {

type: "json"

};

const newOptions = {

...defaultOptions,

...options

};

//headers默认传递json格式数据,这里也可以设置token,每次调用都会携带

if (localStorage.getItem("token")) {

newOptions.headers = {

// 'Authorization': 'Basic b3JkZXItc2VydmVyOjEyMzQ1Ng==',

'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

export default http

//在main.js下面挂载 http.js文件

import http from '@/utils/http.js';

Vue.prototype.http = http;

//登陆保存token信息接口

this.http({

method: "post",

url: "/xxxxx/user",

type: "form",

headers: { Authorization:"Basicb3JkZXItc2VydmVyOjEyMzQ1Ng==" },

data: {}

}).then(function(res) {

let expires_time =

new Date().getTime() +

parseInt(res.data.token.expires_in * 0.8) * 1000;

let token = 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刷新版机制的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对乐购源码网址的支持!

如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

你可能感兴趣的:(vue拦截器刷新登陆页面)