news 2026/7/6 14:20:59

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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;
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/29 0:00:31

HTML5 与 H5:别再让你的专业度在称呼中流失

在中国互联网行业的日常交流中&#xff0c;很少有一个词像“H5”这样被高频使用&#xff0c;却又被如此普遍地误解。当你听到有人说“做一个 H5”时&#xff0c;对方指的往往是一个在微信朋友圈传播的精美幻灯片&#xff0c;或者是一个简单的营销小游戏。然而&#xff0c;当你打…

作者头像 李华
网站建设 2026/6/28 23:27:23

3-VueAjax

什么是Vue Vue是一款用于构建用户界面的渐进式的JavaScript框架。官方网站&#xff1a;https://cn.vuejs.org/ 前端负责将数据以美观的样式呈现出来&#xff0c;而数据最终又要在数据库服务器中存储并管理。前端想要拿到数据&#xff0c;就需要请求服务器。然后服务器将数据返…

作者头像 李华
网站建设 2026/6/29 0:15:02

基于springBoot的房屋租赁管理系统

房屋租赁管理系统的背景意义 市场需求驱动 随着城市化进程加快&#xff0c;流动人口增多&#xff0c;房屋租赁需求持续增长。传统租赁方式依赖中介或线下沟通&#xff0c;效率低且信息不透明。数字化管理系统能优化流程&#xff0c;提升供需匹配效率&#xff0c;降低交易成本…

作者头像 李华
网站建设 2026/6/29 15:01:18

Java基于SSM+JSP的智慧农业无人机租赁系统的设计与实现

项目说明 农业无人机是一种在现代农业中广泛应用的无人机设备&#xff0c;它可以通过遥控或自主飞行&#xff0c;进行一系列农业作业。这些无人机通常配备有高分辨率相机和绘图设备&#xff0c;可以用于进行土地勘测、作物评估、农药喷洒等农业活动。无人机在农业领域的应用&am…

作者头像 李华
网站建设 2026/6/25 22:09:02

学长亲荐2026专科生AI论文工具TOP9:开题报告神器大测评

学长亲荐2026专科生AI论文工具TOP9&#xff1a;开题报告神器大测评 2026年专科生AI论文工具测评&#xff1a;如何选对“开题报告神器”&#xff1f; 随着AI技术在学术领域的广泛应用&#xff0c;越来越多的专科生开始借助智能写作工具提升论文撰写效率。然而&#xff0c;面对市…

作者头像 李华
网站建设 2026/6/29 14:29:23

今天面了一个来字节要求月薪23K,明显感觉他背了很多面试题...

最近有朋友去字节面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

作者头像 李华