uniapp 微信小程序无感刷新token

一、微信静默登录

// 登录方法
export function myLogin() {
	return new Promise((resolve, reject) => {
		uni.login({
			provider: 'weixin',
			success: (re) => {
				let {
					code
				} = re
				
				// 根据公司要求具体配置
				let obj = {
					'Content-Type': 'application/x-www-form-urlencoded',
					'mptype': 'ggws_miniprogram',
				}

				uni.request({
					url: baseUrl,
					data: `act=10001&code=${code}`,
					method: 'POST', // POST请求
					header: obj,
					success: (log) => {
						if (log.data.errcode == 0) {
							let {
								wxToken,
								wxHeader,
								openid
							} = log.data.data.datalist[0]

							uni.setStorageSync("token", wxToken)
							uni.setStorageSync("wxHeader", wxHeader)
							resolve(log.data)
						}
					},
					fail(err) {
						console.log(err);
					}
				})
			}
		})
	})
}

二、在封装的request请求中 拦截token过期

let isRefreshing = false // 是否正在刷新的标记
let requests = [] //重试队列

export function myRequest(data) {
	let obj = {
			'Content-Type': 'application/x-www-form-urlencoded',
			'mptype': wxHeader,
			'mptoken': token
			}
	return new Promise((resolve, reject) => {
		// request请求
		uni.request({
			url: baseUrl, // 基准路径
			data: data, // 参数
			method: 'POST', // POST请求
			header: obj,
			success: async res => {
				if (res.statusCode == 200) {

					//  token过期时 根据token过期码 这里是4000和40007为token过期
					if (res.data.errcode == 4000 || res.data.errcode == 4007) {
						//这里是重点:让这个Promise一直处于Pending状态(即不调用resolve)
						//也就是说 先把需要用到token的请求以pending的状态存入数组
						new Promise((reslove2) => {
							requests.push(() => {
								resolve(myRequest(data))
							})
						})
						
						// 判断是否是正在获取新的token 节省流量
						if (!isRefreshing) {
							isRefreshing = true
							// 调用获取token的方法
							return myLogin().then(re => {
								// 重新设置请求头中的参数 
								// 这里使用的是本地缓存 所以改变本地缓存之后 后续在请求的时候 直接拿本地缓存的token
								wxHeader = uni.getStorageSync("wxHeader")
								token = uni.getStorageSync("token")
								// 拿到新的token之后 重新执行 token过期之前的请求
								requests.forEach((cb) => cb(data))
								requests = []
								return
							}).finally(() => {
								isRefreshing = false
							})
						}
					} else {
						resolve(res.data)
					}
				} else {
					reject(res)
				}
			},
			fail: (err) => {
				reject(err)
				showErr("网络异常!")
			},
		})
	})
}

还有一个方法是 使用拦截器 uni.request.interceptors
此篇文章仅供个人记录。

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了衣李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值