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

uniapp 请求封装!Token 过期自动刷新+队列缓存!CV即用

作为一名 uniapp 搬砖人,谁没被 Token 过期搞得头大过?接口请求一半突然 401,用户体验直接拉胯,手动刷新?重复请求?回调地狱?不存在的!今天就给大家分享一套我实战打磨的请求封装方案,专治各种 Token 过期不服,代码可直接 CV 食用😜

🎯 先说说痛点(你是不是也踩过这些坑)

  1. Token 过期了,接口直接报错,用户一脸懵
  2. 多接口同时 401,重复刷新 Token,服务器直接懵
  3. 刷新 Token 后,原来的请求得重新发,逻辑绕到晕
  4. 配置合并乱七八糟,header 传参总是少东西

🚀 核心实现思路(划重点!)

直接上核心代码,关键地方我都标好了注释,cv稍微改点就行,code判断根据自己后端改,给什么吃什么,懂得都懂:

// 获取全局应用实例 const app = getApp(); // 默认配置 const DEFAULT_CONFIG = { baseURL: 'http://192.168.81.23:8080', timeout: 10000, header: { 'Content-Type': 'application/json' } } // 导入登录接口 import { login } from '@/api/index.js'; // 🔥 核心1:防重复刷新Token const loginExpired = async () => { // 防止重复刷新:如果正在刷新,返回等待的 Promise if (app.globalData.isRefreshing) { return new Promise((resolve, reject) => { app.globalData.refreshSubscribers.push({ resolve, reject }); }); } app.globalData.isRefreshing = true; try { const { code } = await uni.login(); const res = await login({ code }); // 校验登录接口业务码 if (res.code !== 200) { throw new Error(res.msg || '认证失败,请联系管理员'); } // 提取有效 Token const newToken = res.data?.token || res.token || res.msg; if (!newToken) { throw new Error('刷新后未获取到有效Token'); } uni.setStorageSync('token', newToken); // 执行所有挂起的请求并清空队列 app.globalData.refreshSubscribers.forEach(({ resolve }) => resolve(true)); app.globalData.refreshSubscribers = []; return true; } catch (err) { console.error('刷新 Token 失败:', err); // 刷新失败时,拒绝所有挂起的请求 app.globalData.refreshSubscribers.forEach(({ reject }) => reject(err)); app.globalData.refreshSubscribers = []; uni.showToast({ title: err.message.includes('联系管理员') ? '认证失败,请联系管理员' : '认证失败,请重新登录', icon: 'none', duration: 2000 }); throw err; } finally { app.globalData.isRefreshing = false; } }; // 🔥 核心2:带重试的请求封装 export const request = (options = {}, retryCount = 0) => { // 初始化全局数据 if (!app.globalData) app.globalData = {}; if (app.globalData.isRefreshing === undefined) app.globalData.isRefreshing = false; if (!app.globalData.refreshSubscribers) app.globalData.refreshSubscribers = []; // 读取Token const token = uni.getStorageSync('token') // 修复header合并逻辑(别再让header丢参数了!) const config = { ...DEFAULT_CONFIG, ...options, header: { ...DEFAULT_CONFIG.header, ...options.header, 'Authorization': `Bearer ${token || ''}`, 'platform': uni.getStorageSync('platform') || '', 'token': token || '' } } const { baseURL, url, method = 'GET', data, header, timeout } = config const fullUrl = baseURL + url; const MAX_RETRY = 1; // 最大重试次数,防止无限循环 // 封装请求逻辑 const requestHandler = () => { return new Promise((resolve, reject) => { uni.request({ url: fullUrl, method, data, header, timeout, success: (res) => { const { statusCode, data: responseData } = res; const code = responseData.code; // 正常返回 if (statusCode === 200 && code === 200) { resolve(responseData); } // Token 过期(401)且未超过最大重试次数 else if (code === 401 && retryCount < MAX_RETRY) { loginExpired() .then(() => { // 重试时次数+1 request(options, retryCount + 1).then(resolve).catch(reject); }) .catch(reject); } // 其他错误 else { const errMsg = code === 401 ? 'Token 失效且刷新失败,请重新登录' : (responseData.msg || '请求失败'); reject(new Error(errMsg)); } }, fail: (err) => { reject(new Error(`网络请求失败: ${err.errMsg}`)); } }); }); }; return requestHandler(); }; // 快捷方法(GET/POST直接用,懒人福音) request.get = (url, data, options) => request({...options, url, method: 'GET', data}); request.post = (url, data, options) => request({...options, url, method: 'POST', data}); export default request;
http://www.jsqmd.com/news/285602/

相关文章:

  • 2026年1月深圳跨境电商财税服务厂家推荐榜:合规记账/税务筹划/风险规避/代理申报一站式解决方案深度解析
  • C#每日面试题-简述反射
  • 日程7
  • 【Redis典型应用——缓存详解】 - 指南
  • C#每日面试题-简述异常处理
  • 重庆明镜滩项目-11-脚本学习-260122DataPreV5MissAna2
  • James 个人介绍(用于企业数字化服务咨询)
  • 勾股定理简单学习
  • Spring Boot 三种方式登录系统:集成微信扫码、短信验证码、邮箱验证码
  • Oracle 19c入门学习教程,从入门到精通,Oracle 数据表对象 —— 语法知识点详解与案例实践(10)
  • Cadence推出人工智能语音助手Tensilica HiFi iQ DSP IP
  • 鸿蒙 HarmonyOS 6 | 系统能力 (04):构建专业级媒体应用 PhotoAccessHelper 与复杂媒体库管理
  • 基于python的智慧农场管理系统
  • 【鸿蒙原生开发会议随记 Pro】拒绝面条代码 基于 MVVM 的代码架构与状态管理选型
  • aiSim领衔!国内外自动驾驶仿真软件大全:热门推荐与选择指南
  • 芒格的“反向激励“分析在量子计算云服务定价中的应用
  • 基于springboot的植物花卉销售管理系统
  • 20252803-Linux安全类实验-ShellShock 攻击实验 - 详解
  • 铟材料:稀散金属隐形明星,半导体+光伏核心刚需
  • 自动驾驶仿真软件推荐:康谋aiSim——ISO 26262 ASIL-D 认证的高保真选择
  • 关于Uvicorn:一个遵循ASGI规范的异步Web服务器
  • 9个最佳性能测试工具(2026)
  • 058.质数判断 +质数筛 + 质因子分解
  • 超融合 “进化论”:当 HCI 遇上云原生技术栈,下一代基础设施雏形初现
  • 从零构建云原生“试验田”:超融合的自我修养
  • 智慧园区智能照明控制系统解决方案
  • 3-VueAjax
  • 基于springBoot的动漫分享系统的设计与实现
  • 天然蛋白与重组蛋白的技术区别与实验应用全解析:科研试剂视角下的最佳指南
  • 2026年还在靠“开机等单”跑网约车?学会这几条,超越同城80%的司机!