当前位置: 首页 > 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.lryc.cn/news/583415.html

相关文章:

  • Docker 高级管理--容器通信技术与数据持久化
  • [论文阅读] 软件工程 | 一篇关于开源许可证管理的深度综述
  • 图像处理中的模板匹配:原理与实现
  • LabVIEW前面板颜色修改
  • 利用编码ai工具cursor写单元测试
  • MCP快速入门—快速构建自己的服务器
  • 如何使用Pytest进行测试?
  • Android-重学kotlin(协程基础)新学习总结
  • MATLAB基于voronoi生成三维圆柱形
  • 2025年人工智能、虚拟现实与交互设计国际学术会议
  • Matlab-Simulink之步长
  • PlantUML 在 IDEA 中文版中的安装与使用指南
  • VR重现红军过雪山:一场穿越时空的精神洗礼​
  • VR/AR在HMI中的创新应用:远程协作与维修的沉浸式体验
  • 【图像处理基石】图像超分辨率有哪些研究进展值得关注?
  • 【SQL】使用UPDATE修改表字段的时候,遇到1054 或者1064的问题怎么办?
  • git上传大文件启用LFS git报错 the remote end hung up unexpectedly
  • ReactNative【实战系列教程】我的小红书 6 -- 购物(含商品搜索、商品分类、商品列表)
  • 【RidgeUI AI+系列】猜密码游戏
  • 2025快手创作者中心发布视频python实现
  • Python 项目快速部署到 Linux 服务器基础教程
  • Android 系统默认代码,如何屏蔽相册分享功能
  • cJSON数组操作函数使用指南
  • AJAX 学习
  • Go语言高级面试必考:切片(slice)你真的掌握了吗?
  • 11.7 ChatGPT奖励模型完全解读:RLHF核心技术深度剖析与Hugging Face实战
  • 从传统到智能:地质灾害风险评估、易发性分析与灾后重建;AI大语言模型DeepSeek、ChatGPT、GIS、Python和机器学习深度融合
  • 李宏毅NLP-9-语音转换
  • 大数据在UI前端的应用深化:用户行为模式的挖掘与预测性分析
  • Java基础--stream的使用