vue无感刷新和小程序思路是一样的。只是有很多细节需要处理,相对于vue比较复杂,稍不注意就进入死循环,在写项目中,总结一下发出来:
小程序中绝大部分的 API 都支持返回 Promise,也有几个 API 不支持返回 Promise,其中就包含 wx.request
,开发中需要自行对 wx.request
进行封装也可以使用第三方的封装好的模块。
下载第三方包:npm install wechat-http
在utils创建http.js文件封装,设置基地址、请求拦截器,响应拦截器
挂载小程序、暴露方法等
实现无感刷新代码:
// 封装请求函数
// 导入请求插件
import http from 'wechat-http'
// 设置基地址
http.baseURL = 'https://live-api.itheima.net/'
// 请求拦截器
http.intercept.request = (options) => {
// console.log(options);
// 设置请求头
const token = 'Bearer ' + wx.getStorageSync('tokenData').token
const defaultHeader = {}
if (token) defaultHeader.Authorization = token
// 顺序一定是token在前,方便刷新token,能覆盖
//这里就是刷新token不进入死循环的关键,如果顺序放错,在响应拦截器,利用refreshToken设置的请求头就无法覆盖现在的旧token,位置不能颠倒
options.header = { ...defaultHeader, ...options.header }
// 发请求
return options
}
// 响应拦截器
http.intercept.response = async (result) => {
// console.log('请求', result);
//401==token过期
if (result.statusCode === 401) {
//refreshToken过期的处理:
//如果在响应体config的请求路径携带刷新token请求的路径,就证明已经refreshToken已经过期,打回
登录页重新登录
if (result.config.url.includes('/c')) {
//获取登录后跳转的页面路径,传递参数,在登录页做判断,进行跳转
const Pages = getCurrentPages()
const url = Pages[Pages.length - 1].route
console.log(url);
return wx.redirectTo({
url: `/pages/login/index?url=${url}`,
})
}
//利用refreshToken发请求获取新token
const res = await http({
url: '/refreshToken',
method: 'POST',
header: {
...result.config.header,
Authorization: 'Bearer ' + wx.getStorageSync('tokenData').refreshToken
},
})
// console.log('成功', res);
// 保存新token
wx.setStorageSync('tokenData', res.data)
//实现无感刷新
// console.log(result.config) // 发起请求时的所有参数
return http({
...result.config,
header: {
...result.config.header,
Authorization: 'Bearer ' + res.data.token//新token发请求
}
})
}
// 拦截器处理后的响应结果
return result.data//数据剥离
}
// 挂载实例
wx.http = http
// 暴露
export default http
小结:return的位置很重要,一定不能忘记return,不然容易进入死循环。