UniApp 中封装 HTTP 请求与 Token 管理(附Demo)

ops/2025/3/3 4:39:48/

目录

  • 1. 基本知识
  • 2. Demo
  • 3. 拓展

1. 基本知识

从实战代码中学习,上述实战代码来源:芋道源码/yudao-mall-uniapp

在这里插入图片描述

该代码中,通过自定义 request 函数对 HTTP 请求进行了统一管理,并且结合了 Token 认证机制

  1. 请求封装原理,request 函数是对 uni.request 的一个封装
  • 动态设置请求头:根据 config 的配置,决定是否需要在请求头中附加 Authorization(Bearer Token)。Token 是从本地存储中获取的
  • 根据环境区分不同的 Base URL:根据当前的开发环境(development 或 production),动态设置请求的基础 URL(baseUrl)
  • 统一处理请求参数:config.params 会被转化成查询字符串,拼接到请求的 URL 后面
  • Promise 封装异步操作:请求通过 uni.request 发出,并将返回的 response 数据封装为一个 Promise,使得调用 request 的地方可以使用 then 或 catch 来处理结果
  1. Token 认证管理原理
  • Token 存储:uni.setStorageSync 和 uni.getStorageSync 被用来在客户端本地存储 ACCESS_TOKEN 和 REFRESH_TOKEN,这两个 Token 被用于身份验证
  • 获取 Token:在每次 HTTP 请求时,首先会检查请求是否需要 Token(通过 config.headers.isToken 判断)。如果需要,就从本地存储中获取 AccessToken 并加入到请求头中
  • Token 过期处理:当请求返回的状态码为 401 时,表示 Token 已过期,此时会弹出提示框,让用户重新登录并清除旧的 Token
  1. 错误处理机制
  • 网络错误:封装了常见的网络错误(如超时、服务器错误等),并提供了友好的提示
  • 接口返回错误:统一处理接口返回的错误,错误信息根据 res.data.code 的值来决定,如果返回的是 500 错误或其他非 200 的错误,则通过 toast 提示给用户
  • 401 错误处理:当返回状态码为 401 时,表示 Token 过期或无效,代码会自动处理登出流程

2. Demo

根据实战中的Demo,给出一版通用的Demo:

封装request的时候,需要与token结合:

js">token comment">// utils/request.js
token keyword">import token punctuation">{ getAccessTokentoken punctuation">, setTokentoken punctuation">, removeToken token punctuation">} token keyword">from token string">'@/utils/auth'token punctuation">;
token keyword">import config token keyword">from token string">'@/config'token punctuation">;
token keyword">import errorCode token keyword">from token string">'@/utils/errorCode'token punctuation">;
token keyword">import token punctuation">{ toasttoken punctuation">, showConfirm token punctuation">} token keyword">from token string">'@/utils/common'token punctuation">;token keyword">let timeout token operator">= token number">10000token punctuation">;
token keyword">let baseUrl token operator">= processtoken punctuation">.envtoken punctuation">.token constant">NODE_ENV token operator">=== token string">'development' token operator">? configtoken punctuation">.devbaseUrl token operator">: configtoken punctuation">.prodbaseUrltoken punctuation">;token keyword">const token function-variable function">request token operator">= token parameter">config token operator">=> token punctuation">{token keyword">const isToken token operator">= token punctuation">(configtoken punctuation">.headers token operator">|| token punctuation">{token punctuation">}token punctuation">)token punctuation">.isToken token operator">=== token boolean">falsetoken punctuation">;configtoken punctuation">.header token operator">= configtoken punctuation">.header token operator">|| token punctuation">{token punctuation">}token punctuation">;token keyword">if token punctuation">(token function">getAccessTokentoken punctuation">(token punctuation">) token operator">&& token operator">!isTokentoken punctuation">) token punctuation">{configtoken punctuation">.headertoken punctuation">[token string">'Authorization'token punctuation">] token operator">= token string">'Bearer ' token operator">+ token function">getAccessTokentoken punctuation">(token punctuation">)token punctuation">;token punctuation">}configtoken punctuation">.headertoken punctuation">[token string">'tenant-id'token punctuation">] token operator">= token string">'1'token punctuation">; token comment">// 强制设置租户 IDtoken keyword">if token punctuation">(configtoken punctuation">.paramstoken punctuation">) token punctuation">{token keyword">let url token operator">= configtoken punctuation">.url token operator">+ token string">'?' token operator">+ token function">tansParamstoken punctuation">(configtoken punctuation">.paramstoken punctuation">)token punctuation">;url token operator">= urltoken punctuation">.token function">slicetoken punctuation">(token number">0token punctuation">, token operator">-token number">1token punctuation">)token punctuation">;configtoken punctuation">.url token operator">= urltoken punctuation">;token punctuation">}token keyword">return token keyword">new token class-name">Promisetoken punctuation">(token punctuation">(token parameter">resolvetoken punctuation">, rejecttoken punctuation">) token operator">=> token punctuation">{unitoken punctuation">.token function">requesttoken punctuation">(token punctuation">{token literal-property property">methodtoken operator">: configtoken punctuation">.method token operator">|| token string">'get'token punctuation">,token literal-property property">timeouttoken operator">: configtoken punctuation">.timeout token operator">|| timeouttoken punctuation">,token literal-property property">urltoken operator">: configtoken punctuation">.baseUrl token operator">|| baseUrl token operator">+ configtoken punctuation">.urltoken punctuation">,token literal-property property">datatoken operator">: configtoken punctuation">.datatoken punctuation">,token literal-property property">headertoken operator">: configtoken punctuation">.headertoken punctuation">,token literal-property property">dataTypetoken operator">: token string">'json'token punctuation">}token punctuation">)token punctuation">.token function">thentoken punctuation">(token parameter">response token operator">=> token punctuation">{token keyword">let token punctuation">[errortoken punctuation">, restoken punctuation">] token operator">= responsetoken punctuation">;token keyword">if token punctuation">(errortoken punctuation">) token punctuation">{token function">toasttoken punctuation">(token string">'后端接口连接异常'token punctuation">)token punctuation">;token function">rejecttoken punctuation">(token string">'后端接口连接异常'token punctuation">)token punctuation">;token keyword">returntoken punctuation">;token punctuation">}token keyword">const code token operator">= restoken punctuation">.datatoken punctuation">.code token operator">|| token number">200token punctuation">;token keyword">const msg token operator">= errorCodetoken punctuation">[codetoken punctuation">] token operator">|| restoken punctuation">.datatoken punctuation">.msg token operator">|| errorCodetoken punctuation">[token string">'default'token punctuation">]token punctuation">;token keyword">if token punctuation">(code token operator">=== token number">401token punctuation">) token punctuation">{token function">showConfirmtoken punctuation">(token string">'登录状态已过期,您可以继续留在该页面,或者重新登录?'token punctuation">)token punctuation">.token function">thentoken punctuation">(token parameter">res token operator">=> token punctuation">{token keyword">if token punctuation">(restoken punctuation">.confirmtoken punctuation">) token punctuation">{token function">removeTokentoken punctuation">(token punctuation">)token punctuation">;unitoken punctuation">.token function">reLaunchtoken punctuation">(token punctuation">{ token literal-property property">urltoken operator">: token string">'/pages/login' token punctuation">}token punctuation">)token punctuation">;token punctuation">}token punctuation">}token punctuation">)token punctuation">;token function">rejecttoken punctuation">(token string">'无效的会话,或者会话已过期,请重新登录。'token punctuation">)token punctuation">;token punctuation">} token keyword">else token keyword">if token punctuation">(code token operator">=== token number">500token punctuation">) token punctuation">{token function">toasttoken punctuation">(msgtoken punctuation">)token punctuation">;token function">rejecttoken punctuation">(token string">'500'token punctuation">)token punctuation">;token punctuation">} token keyword">else token keyword">if token punctuation">(code token operator">!== token number">200token punctuation">) token punctuation">{token function">toasttoken punctuation">(msgtoken punctuation">)token punctuation">;token function">rejecttoken punctuation">(codetoken punctuation">)token punctuation">;token punctuation">}token function">resolvetoken punctuation">(restoken punctuation">.datatoken punctuation">)token punctuation">;token punctuation">}token punctuation">)token punctuation">.token function">catchtoken punctuation">(token parameter">error token operator">=> token punctuation">{token keyword">let token punctuation">{ message token punctuation">} token operator">= errortoken punctuation">;token keyword">if token punctuation">(message token operator">=== token string">'Network Error'token punctuation">) message token operator">= token string">'后端接口连接异常'token punctuation">;token keyword">else token keyword">if token punctuation">(messagetoken punctuation">.token function">includestoken punctuation">(token string">'timeout'token punctuation">)token punctuation">) message token operator">= token string">'系统接口请求超时'token punctuation">;token keyword">else token keyword">if token punctuation">(messagetoken punctuation">.token function">includestoken punctuation">(token string">'Request failed with status code'token punctuation">)token punctuation">) message token operator">= token string">'系统接口' token operator">+ messagetoken punctuation">.token function">substrtoken punctuation">(messagetoken punctuation">.length token operator">- token number">3token punctuation">) token operator">+ token string">'异常'token punctuation">;token function">toasttoken punctuation">(messagetoken punctuation">)token punctuation">;token function">rejecttoken punctuation">(errortoken punctuation">)token punctuation">;token punctuation">}token punctuation">)token punctuation">;token punctuation">}token punctuation">)token punctuation">;
token punctuation">}token punctuation">;token keyword">export token keyword">default requesttoken punctuation">;

对应的token文件:

js">token comment">// utils/auth.js
token keyword">const AccessTokenKey token operator">= token string">'ACCESS_TOKEN'token punctuation">;
token keyword">const RefreshTokenKey token operator">= token string">'REFRESH_TOKEN'token punctuation">;token keyword">export token keyword">function token function">getAccessTokentoken punctuation">(token punctuation">) token punctuation">{token keyword">return unitoken punctuation">.token function">getStorageSynctoken punctuation">(AccessTokenKeytoken punctuation">)token punctuation">;
token punctuation">}token keyword">export token keyword">function token function">getRefreshTokentoken punctuation">(token punctuation">) token punctuation">{token keyword">return unitoken punctuation">.token function">getStorageSynctoken punctuation">(RefreshTokenKeytoken punctuation">)token punctuation">;
token punctuation">}token keyword">export token keyword">function token function">setTokentoken punctuation">(token parameter">tokentoken punctuation">) token punctuation">{unitoken punctuation">.token function">setStorageSynctoken punctuation">(AccessTokenKeytoken punctuation">, tokentoken punctuation">.accessTokentoken punctuation">)token punctuation">;unitoken punctuation">.token function">setStorageSynctoken punctuation">(RefreshTokenKeytoken punctuation">, tokentoken punctuation">.refreshTokentoken punctuation">)token punctuation">;
token punctuation">}token keyword">export token keyword">function token function">removeTokentoken punctuation">(token punctuation">) token punctuation">{unitoken punctuation">.token function">removeStorageSynctoken punctuation">(AccessTokenKeytoken punctuation">)token punctuation">;unitoken punctuation">.token function">removeStorageSynctoken punctuation">(RefreshTokenKeytoken punctuation">)token punctuation">;
token punctuation">}

相关接口请求:

js">token comment">// 在页面中调用封装的请求方法
token keyword">import request token keyword">from token string">'@/utils/request'token punctuation">;token keyword">export token keyword">default token punctuation">{token literal-property property">methodstoken operator">: token punctuation">{token function">fetchDatatoken punctuation">(token punctuation">) token punctuation">{token function">requesttoken punctuation">(token punctuation">{token literal-property property">urltoken operator">: token string">'/api/getData'token punctuation">,token literal-property property">methodtoken operator">: token string">'GET'token punctuation">,token literal-property property">paramstoken operator">: token punctuation">{ token literal-property property">idtoken operator">: token number">123 token punctuation">}token punctuation">}token punctuation">)token punctuation">.token function">thentoken punctuation">(token parameter">response token operator">=> token punctuation">{consoletoken punctuation">.token function">logtoken punctuation">(token string">'数据:'token punctuation">, responsetoken punctuation">)token punctuation">;token punctuation">}token punctuation">)token punctuation">.token function">catchtoken punctuation">(token parameter">error token operator">=> token punctuation">{consoletoken punctuation">.token function">logtoken punctuation">(token string">'请求失败:'token punctuation">, errortoken punctuation">)token punctuation">;token punctuation">}token punctuation">)token punctuation">;token punctuation">}token punctuation">}
token punctuation">}

3. 拓展

process.env.NODE_ENV 是 Node.js 环境中用于获取当前应用运行环境的一个变量

在大多数前端框架(如 Vue、React)以及后端框架(如 Express)中,process.env.NODE_ENV 被广泛用于区分不同的开发环境

前端vue中可能已经标明了
在开发模式下:NODE_ENV=development npm run dev
在生产模式下:NODE_ENV=production npm run build
在 npm 脚本中,可以通过 cross-env 等工具来跨平台设置环境变量:

token string">"scripts"token operator">: token punctuation">{token string">"dev"token operator">: token string">"cross-env NODE_ENV=development vue-cli-service serve"token punctuation">,token string">"build"token operator">: token string">"cross-env NODE_ENV=production vue-cli-service build"
token punctuation">}

另外一个接口超时时间,全局默认是20秒,如果时长不对,可以在单独某个接口设置:

js">token comment">// 上传图片
token function">uploadImagetoken punctuation">(token parameter">datatoken punctuation">) token punctuation">{token keyword">return token function">uploadtoken punctuation">(token punctuation">{token literal-property property">urltoken operator">: token string">'/infra/file/upload'token punctuation">,token literal-property property">methodtoken operator">: token string">'upload'token punctuation">,token literal-property property">filePathtoken operator">: datatoken punctuation">.filePathtoken punctuation">,token literal-property property">timeouttoken operator">: token number">30000  token comment">// 设置超时时间为30秒token punctuation">}token punctuation">)token punctuation">;
token punctuation">}

http://www.ppmy.cn/ops/162389.html

相关文章

C++ 设计模式 十二:责任链模式 (读书 现代c++设计模式)

责任链 文章目录 责任链场景指针链代理链总结**责任链模式的核心思想****何时需要使用责任链模式?****责任链模式解决的核心问题****与其他设计模式的协同使用****与其他模式的对比****经典应用场景****实现步骤与关键点****注意事项****总结** 今天是第十二种设计模…

基于Java+Jsp+SpringMVC漫威手办商城系统设计和实现

基于JavaJspSpringMVC漫威手办商城系统设计和实现 🍅 作者主页 网顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统 &am…

基于C语言模拟一个简易的冯诺依曼式计算机CPU的工作(bupt计导)

1 高层数据结构设计 (包括:重要的数据常量定义、数据变量定义,即各模块要共享的数据类型和参数设计,相当于头文件内容,加文字描述) 1.1 全局常量/变量定义 int Memory[50000]; //内存,下标0-1638…

(IDE接入DeepSeek)简单了解DeepSeek接入辅助开发与本地部署建议

重点:IDE接入DeepSeek是否收费 收费! 本文章主要是为了给小白避雷,目前很多文章告诉大家怎么接入DeepSeek,但是并未告知大家是否收费。如果是想白嫖的,就可以不用去接入了。 一、引言 最近爆火的AI人工智能工具DeepSe…

Python使用总结之Python文本转语音引擎:pyttsx3完全指南

Python使用总结之Python文本转语音引擎:pyttsx3完全指南 在开发需要语音输出功能的应用时,文本转语音(TTS)技术是一个非常有用的工具。Python的pyttsx3库提供了一个简单且离线的方式来实现这一功能,无需依赖互联网连接或外部API。本文将详细…

SQL-Server链接服务器访问Oracle数据

SQL Server 链接服务器访问 Oracle 离线安装 .NET Framework 3.5 方法一:使用 NetFx3.cab 文件 下载 NetFx3.cab 文件,并将其放置在 Windows 10 系统盘的 C:Windows 文件夹中。 以管理员身份运行命令提示符,输入以下命令并回车: …

用 AI 工具实现被动收入:自动化内容生成与发布

——————————————————— 用 AI 工具实现被动收入:自动化内容生成与发布 嘿,朋友们!今天聊点硬核又实在的东西——如何用AI工具实现被动收入。 别急着划走!我知道很多人一听“被动收入”就觉得是个遥不可及的梦…

Spark基础篇-Application、Job、Stage 和 Task

Spark基础篇 单独看看Application、Job、Stage 和 Task 在 Apache Spark 中,Application、Job、Stage 和 Task 是任务调度和执行的四个核心层级概念,它们构成从宏观到微观的完整执行流程。以下是对它们的详细解释及其关系: 1. Application(应用程序) 定义:一个完整的 Sp…