一、微信静默登录

// 登录方法
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
此篇文章仅供个人记录。

Logo

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

更多推荐