当前位置: 首页 > news >正文

uniapp小程序无感刷新token

  • request.js
// request.js
import {getApptoken,getStoredApptoken
} from './tokenRequest' // 从合并模块导入// 全局配置
const MAX_RETRIES = 1 // 最大重试次数
const baseURL = 'https://your-api.com'// 请求队列和刷新状态
let requestsQueue = []
let isRefreshing = false// 核心请求函数
export const request = config => {return new Promise((resolve, reject) => {// 应用请求拦截器const processedConfig = requestInterceptor({baseURL,method: 'POST',needRefreshToken: true,retryCount: 0, // 记录重试次数...config})// 处理参数拼接(原URL有参数则用&,否则用?)const separator = processedConfig.url.includes('?') ? '&' : '?'const url = `${processedConfig.baseURL}${processedConfig.url}${separator}token=${processedConfig.apptoken || ''}`// 发起请求uni.request({...processedConfig,url,success: response => {// 应用响应拦截器responseInterceptor(response, processedConfig).then(resolvedData => resolve(resolvedData)).catch(err => reject(err))},fail: error => {console.error(`请求失败:${processedConfig.url}`, error)reject(error)}})})
}// 请求拦截器:统一处理请求前逻辑
const requestInterceptor = config => {config.header = {'Content-Type': 'application/json',...config.header}if (config.needRefreshToken) {const token = getStoredApptoken() // 使用合并模块的工具函数if (token) {config.token = token}}return config
}// 响应拦截器:统一处理响应后逻辑
const responseInterceptor = async (response, config) => {const {data,statusCode} = response// 处理成功响应if (statusCode === 200) {return data}// 处理401/400错误(token过期)if ((statusCode === 401 || statusCode === 400) && config.needRefreshToken) {// 检查是否超过最大重试次数if (config.retryCount >= MAX_RETRIES) {uni.showToast({title: '重试次数过多,请稍后再试',icon: 'none'})return Promise.reject(new Error('重试次数过多'))}// 如果正在刷新token,将请求加入队列等待if (isRefreshing) {return new Promise(resolve => {requestsQueue.push(() => resolve(request({...config,retryCount: config.retryCount + 1})))})}// 开始刷新tokenisRefreshing = truetry {// 获取新的tokenconst refreshSuccess = await getApptoken()if (!refreshSuccess) {return Promise.reject(new Error('获取新的token失败'))}// 重试原请求const retryResponse = await request({...config,retryCount: config.retryCount + 1})// 执行队列中所有挂起的请求requestsQueue.forEach(callback => callback())requestsQueue = []return retryResponse} catch (refreshError) {console.error('刷新token出错', refreshError)uni.showToast({title: '认证失败,请重新登录',icon: 'none'})return Promise.reject(refreshError)} finally {isRefreshing = false // 重置刷新状态}}// 其他错误处理return Promise.reject(new Error(`请求失败,状态码:${statusCode}`))
}// 封装常用请求方法
export const requestPost = (url, data, config = {}) => {return request({url,data,method: 'POST',...config})
}export const requestGet = (url, config = {}) => {return request({url,method: 'GET',...config})
}
  • tokenRequest.js
// tokenRequest.js// 应用配置
const infoObj = {appkey: process.env.ENV_TYPE === 'prod' ? 'C1A1140xxxxxxxxxxxxxxxxxxxxxxxxxxxx' :'3232313xxxxxxxxxxxxxxxxxxxxxxxxxxxx',appSecret: process.env.ENV_TYPE === 'prod' ? '34D7C4Exxxxxxxxxxxxxxxxxxxxxxxxxxxx' :'0A779D4xxxxxxxxxxxxxxxxxxxxxxxxxxxx',token: ''
}
const baseURL = 'https://your-api.com'// 基础请求(无拦截器)
const baseRequest = config => {return new Promise((resolve, reject) => {uni.request({method: 'GET',header: { 'Content-Type': 'application/json' },dataType: 'json',...config,success: response => resolve(response.data), // 直接返回datafail: error => reject(error)})})
}// 获取AppToken
export const getApptoken = () => {return new Promise((resolve, reject) => {const oldtoken = getStoredApptoken()const tokenUrl = `${baseURL}/getToken?token=${oldtoken}`baseRequest({ url: tokenUrl }).then(res => {if (res.token) {infoObj.token = res.tokenuni.setStorageSync('infoObj', JSON.stringify(infoObj))resolve(true)} else {uni.showToast({title: '更新token出错',icon: 'none'})resolve(false)}}).catch(err => {console.error('获取token接口失败', err)uni.showToast({title: '更新token接口出错',icon: 'none'})resolve(false)})})
}// 获取存储的AppToken
export const getStoredApptoken = () => {try {const stored = uni.getStorageSync('infoObj')return stored ? JSON.parse(stored).token : ''} catch (error) {console.error('获取存储的token失败', error)return ''}
}
  • xxx.vue
// 示例:调用POST接口(如需发送数据)
const submitData = async () => {try {const params = { name: 'test', age: 20 };// 调用POST接口(自动拼接token到URL)const res = await requestPost('/api/submit', params);console.log('提交成功', res);} catch (err) {console.error('提交失败', err);}
};
http://www.xdnf.cn/news/1090045.html

相关文章:

  • 【数字后端】- Standard Cell Status
  • 【机器人】Aether 多任务世界模型 | 4D动态重建 | 视频预测 | 视觉规划
  • vue2中使用xgplayer播放流视频
  • Claude Code 开发使用技巧
  • 【Modern C++ Part7】_创建对象时使用()和{}的区别
  • 从0到1:Maven下载安装与配置全攻略
  • vcpkg交叉编译qt等过程记录(未完成)
  • 华为动态路由配置
  • Git基本操作1
  • git 报错fatal: refusing to merge unrelated histories
  • 城市地质大数据平台:透视地下空间,赋能智慧未来
  • 基于物联网的智能家居控制系统设计与实现
  • 从零开始的云计算生活——番外2,MySQL组复制
  • 项目进度管控缺乏闭环,如何形成反馈机制
  • 适老化HMI改造:老年用户界面的字体、触控区域优化策略
  • 想要抢早期筹码?FourMeme专区批量交易教学
  • Kubernetes 存储入门
  • Spring Boot + Vue.js 全栈开发:从前后端分离到高效部署,打造你的MVP利器!
  • NLP自然语言处理04 transformer架构模拟实现
  • 【Java SE】Arrays工具类
  • OpenCV哈希算法------Marr-Hildreth 边缘检测哈希算法
  • 字符串大小比较的方式|函数的多返回值
  • Softhub软件下载站实战开发(十六):仪表盘前端设计与实现
  • 【DOCKER】-2 docker基础
  • 车载以太网-TC8测试-UT(Upper Tester)
  • 基于物联网的智能交通灯控制系统设计
  • RAGflow图像解析与向量化分析
  • 基于模板设计模式开发优惠券推送功能以及对过期优惠卷进行定时清理
  • 文献学习|全面绘制和建模水稻调控组景观揭示了复杂性状背后的调控架构。
  • 【洛谷题单】--顺序结构(一)