不管你是用taro uni 还是vue-cli 或者 react-cli 刷新token这块一通百通 本质上 都一样
我之前讲了一个是 在响应拦截哪里做token刷新 其实这样做还是不好的,因为这样我们发起了请求, 相对来说 还是在请求之前做比较好 那样可以避免 几次请求吧
因为在 axis 中有帮我们处理的拦截器 在uniapp 中也需要我们做一个拦截器
这里直接使用uniapp插件市场找到的一个。 但是其中很多我们可能用不到 我就给删减了很多。
在common下创建一个 http.js
我这里的是最简的版本 什么其他请求和请求日志的都删除了 只留下我用到的
// 拦截器
export default {
config: {
baseUrl: "", // 请求域名的基础地址
header: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/x-www-form-urlencoded",
},
data: {
},
method: "POST", // 默认post请求
dataType: "json" /* 如设为json,会对返回的数据做一次 JSON.parse */,
responseType: "text",
success() {
},
fail() {
},
complete() {
},
},
interceptor: {
request: null,
response: null,
},
request(options) {
if (!options) {
options = {
};
}
options.baseUrl = options.baseUrl || this.config.baseUrl;
options.dataType = options.dataType || this.config.dataType;
options.url = options.baseUrl + options.url;
options.data = options.data || {
};
options.method = options.method || this.config.method;
return new Promise((resolve, reject) => {
let _config = null;
options.complete = (response) => {
let statusCode = response.statusCode;
response.config = _config;
if (this.interceptor.response) {
let newResponse = this.interceptor.response(response);
if (newResponse) {
response = newResponse;
}
}
if (statusCode === 200) {
//成功
resolve(response);
} else {
reject(response);
}
};
_config = Object.assign({
}, this.config, options);
_config.requestId = new Date().getTime();
if (this.interceptor.request) {
this.interceptor.request(_config);
}
uni.request(_config);
});
},
};
然后就是在我们的 request.js中使用了
这里提一句就是 一般来说 token有一个过期时间。我这里判断的是 在距离过期还有一个小时内。用户操作 就会刷新token重新延长12个小时(这个token存在时间不同的公司规定应该是不一样的哦)
let isRefreshing = false, requestQueue = [] // 重新执行队列
// 请求拦截
http.interceptor.request = async (config) => {
let _userToken = uni.getStorageSync('token')
config.header['token'] = _userToken.token
//无感刷新处理
const nowTime = parseInt(new Date().getTime() / 1000); //过期前一个小时
const expireTime = (_userToken.tokenExpiresTime || 0) > 0 ? parseInt(_userToken.tokenExpiresTime) - 3600 : 0;
if (token && nowTime > expireTime) {
if (!isRefreshing) {
// 一次进入一个刷新token
isRefreshing = true
// 刷新token的请求方法 是基于promise 封装的一个请求方法
// 我放在了 vuex中的actions中
const res = await store.dispatch({
type: 'user/refreshToken',
token: _userToken.token,
freshToken: _userToken.freshToken
})
uni.setStorageSync('token', res.Data)
requestQueue.forEach(cb => cb(token));
isRefreshing = false
requestQueue = []; // 清空请求队列
}
const request = new Promise(resolve => {
requestQueue.push(token => {
config.header["token"] = token;
resolve(config);
});
});
return request;
}
return config;
};
这样用户就不用抱怨 我在登录的时候 一直操作着 莫名其妙就掉线了。哈哈哈
关注我 持续更新前端知识。
还有不懂的地方 可以私信我哦