组件库使用uview2.0,http请求基于luch-request,文档添加链接描述,用的小程序匿名登录,直接上代码

import Request from '@/uni_modules/uview-ui/libs/luch-request/index.js' // uview中的luch-request
import store from '@/store/index.js'

//标志当前是否正在刷新token
let isNotRefreshing = true;
//请求队列
let requests = [];

// 创建实例
const request = new Request({
	baseURL: 'https://battery.d.andoner.cn',
	timeout: 30000
})

// 创建单独刷新token实例,防止进入上一个实例拦截器影响后续操作
const request_refresh = new Request({
	baseURL: 'https://battery.d.andoner.cn',
	timeout: 30000
})

// 请求拦截
request.interceptors.request.use((config) => {
	// 添加token
	if (store.state.user.token) {
		config.header['Authorization'] = "JWT " + store.state.user.token
	}
	return config
}, config => {
	return Promise.reject(config)
})

// 响应拦截
request.interceptors.response.use(response => {
	const data = response.data
	// 业务异常拦截
	if (data.code && data.code !== 200 && data.code !== 2000) {
		// 401:token异常
		if (data.code === 401) {
			//首先拿到响应的配置参数,这和请求的配置参数是一样的,包括了url、data等信息,待会需要使用这个config来进行重发
			const config = response.config;
			//如果当前不处于刷新阶段就进行刷新操作
			if (isNotRefreshing) {
				isNotRefreshing = false;
				//返回刷新token的回调的返回值,本来考虑到由于请求是异步的,所以return会先执行,导致返回一个undefined,那么就需要使用async+await,但实际上没有加也成功了
				// 注意这里要使用新的请求实例防止进入拦截器,刷新token接口
				return request_refresh.post('/api/jwt/token/', {
						username: uni.getStorageSync('unionid'),
						password: '123456'
					})
					.then(res => {
						//刷新成功之后,将新的token存起来
						store.commit('user/setToken', res.data.token)
						//执行requests队列中的请求,(requests中存的不是请求参数,而是请求的Promise函数,这里直接拿来执行就好)
						requests.forEach(run => run())
						//将请求队列置空
						requests = []
						//重新执行当前未执行成功的请求并返回
						return request.request(config);
					})
					.catch(() => {})
					.finally(() => {
						isNotRefreshing = true;
					})
			} else {
				//如果当前已经是处于刷新token的状态,就将请求置于请求队列中,这个队列会在刷新token的回调中执行,由于new关键字存在声明提升,所以不用顾虑会有请求没有处理完的情况,这段添加请求的程序一定会在刷新token的回调执行之前执行的
				return new Promise(resolve => {
					//这里加入的是一个promise的解析函数,将响应的config配置对应解析的请求函数存到requests中,等到刷新token回调后再执行
					requests.push(() => {
						resolve(request.request(config));
					})
				})
			}
		}
		// 其他异常 ,对报错进行toast弹出提示
		uni.$u.toast(data.message || data.msg)
		return Promise.reject(data)
	}

	return data.data || data // 直接返回data数据
}, (response) => {
	// 对响应错误做点什么 (statusCode !== 200)
	return Promise.reject(response)
})

export default request

请根据自身项目适当调整

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐