创建request.js文件
export default {
config: {
baseURL: 'https://XXX.com/',//接口URL
isRefreshing :true,
subscribers : [],
referToken() {
let token = '';
return new Promise((resolve, reject) => {
let that = this
if (!token) {
//获取用户信息
uni.login({
provider: 'weixin',
success: (res) => {
//登陆成功的回调
let obj = {
code:res.code,
appid:wx.getAccountInfoSync().miniProgram.appId
}
uni.request({
url: '请求tokenURL',
data: obj,
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded',
},
success: function(res) {
const wx_openid = res.data.data.openid
const token = res.data.data._token
uni.setStorageSync("openid", openid)
uni.setStorageSync("token", token)
resolve(token)
that.onAccessTokenFetched()//执行缓存中的请求
//延迟几秒再将刷新token的开关放开,不然偶尔还是会重复提交刷新token的请求
setTimeout(()=>{
that.isRefreshing = true
},3000)
},
fail: function(err) {
console.log(err)
}
})
},
})
}
})
},
// 响应拦截器
beforeRequest(options = {}) {
return new Promise((resolve, reject) => {
if(!uni.getStorageSync("token")){
if(this.isRefreshing){
this.referToken()
}
this.isRefreshing = false
}
//请求的地址 = 上面设置的域名加上接口封装的地址
options.url = this.baseURL + options.url;
options.method = options.method || "POST";
//添加请求头
options.header = {
contentType: 'application/x-www-form-urlencoded',
token:!uni.getStorageSync("token") ? '' : uni.getStorageSync("token")
};
resolve(options);
});
},
// 刷新token的函数
checkStatus(params) {
//这需要添加一个开关,防止重复请求
if(this.isRefreshing){
this.referToken()
}
this.isRefreshing = false;
// 将token刷新成功后的回调请求缓存
const retryOriginalRequest = new Promise((resolve) => {
this.addSubscriber(()=> {
params.url = params.url.replace(this.baseURL, "");
resolve(this.makeRequest(params))
})
});
return retryOriginalRequest;
},
//执行缓存中的请求
onAccessTokenFetched() {
this.subscribers.forEach((callback)=>{
callback()
})
this.subscribers = [];
},
// 缓存
addSubscriber(callback) {
this.subscribers.push(callback)
},
// 请求拦截器
handleResponse(data,params) {
return new Promise((resolve, reject) => {
const [err, res] = data; //此处data为接口返回值,请根据实际返回内容做出调整
if (res) {
if ( res.data.code == 20000) {
return resolve(res.data);
}
if ( res.data.code == 40000) {
uni.showToast({
title:res.data.msg,
icon:'none'
})
}
if ( res.data.code == 40001) {
console.log("请求失败")
// 重新调起请求
this.checkStatus(params).then(res=>{
resolve(res)
})
}
if(res.data.code == 40002){
console.log("token过期")
// 重新调起请求
this.checkStatus(params).then(res=>{
resolve(res)
})
}
}
if (err !== null) {
return reject(err);
}
})
},
// 用于再次发起请求
makeRequest(options = {}) {
if(options.data !== undefined){
options.data.openid == '' ? options.data.openid = uni.getStorageSync("openid") : ''
}
options.header.token ? options.header.token = uni.getStorageSync("token") : ''
return this.beforeRequest(options).then((opt) => {
return uni.request(opt);
})
.then((res) => this.handleResponse(res,options))
}
},
// request 请求
request(options = {}) {
return this.config.beforeRequest(options).then((opt) => {
return uni.request(opt);
})
.then((res) => this.config.handleResponse(res,options))
},
}
实际封装根据业务需求引入request.js文件即可
此处仅简单举例!!
import request from './request.js'
function postRequest(url, data){
return request.request({
url: url, //接口地址
method: 'post',
data: data,
})
}
module.exports = {
postRequest
}