uni-app无内置全局request拦截器,必须手动封装uni.request实现;所有拦截逻辑需在自定义request函数中通过beforeRequest和afterResponse时机控制,并统一处理请求配置、响应状态及错误分类。

uni-app 没有内置的全局 request 拦截器 API,所谓“拦截器”必须靠手动封装 uni.request 实现,直接调用 uni.request 是无法挂载请求/响应钩子的。
为什么不能直接用 uni.request 加拦截器
因为 uni.request 是一个纯函数调用,不返回可链式操作的实例,也不暴露生命周期钩子。官方从未提供类似 Axios 的 interceptors.request.use 接口。所有“拦截器”方案本质都是:自己写一个 request 函数,在调用 uni.request 前后插入逻辑。
- 常见错误现象:
uni.request.interceptors报错或 undefined —— 这个属性根本不存在 - 有人试图在
main.js里给uni.request增加属性,结果在 H5 或小程序平台失效,因为各端底层实现不同,不可劫持原生方法 - 真正生效的只有「封装一层」:导出你自己的
request方法,项目中所有网络请求都必须显式 import 并调用它
如何封装带拦截能力的 request 方法
核心是控制两个时机:发起请求前(beforeRequest)和收到响应后(afterResponse),并把错误分类处理。
- 请求前统一处理:
baseURL拼接、token注入到header、loading显示、参数序列化(如GET请求自动把data转 query string) - 响应后分三类处理:
-
success回调里判断res.statusCode,200–299 才 resolve 数据,否则 reject -
fail回调捕获网络异常(如超时、断网),不进 success - 业务错误码(如 401、403)单独跳转或清缓存,避免每个接口重复写
-
- 示例关键片段(非完整类,够用):
const request = (options) => { // beforeRequest const config = { ...options, url: 'https://api.example.com' + options.url, header: { ...options.header, Authorization: uni.getStorageSync('token') || '' } } return new Promise((resolve, reject) => { uni.request({ ...config, success: (res) => { // afterResponse if (res.statusCode === 401) { uni.removeStorageSync('token') uni.navigateTo({ url: '/pages/login/login' }) return reject(new Error('unauthorized')) } if (res.statusCode >= 200 && res.statusCode < 300) { resolve(res.data) } else { reject(res) } }, fail: (err) => reject(err) }) }) }
拦截器容易被忽略的兼容性坑
封装看似简单,但跨端行为差异会直接导致线上报错。
-
uni.getStorageSync在 App 端可能抛异常(尤其 iOS),建议包一层 try/catch,失败时 fallback 为空字符串或默认值 -
uni.navigateTo跳登录页时,路径必须严格匹配pages.json中声明的路径(不带.vue,斜杠方向为/,大小写敏感),否则 H5 可能白屏,小程序报page is not found - 上传文件用
uni.uploadFile,它和uni.request是两套 API,你的封装函数默认不覆盖它——需要单独再封装一个upload方法 - 微信小程序真机调试时,
header中的content-type若设为application/json但 data 是 Object,会静默失败;应确保 data 是 string 或删掉该 header 让微信自动设
最麻烦的点其实是「所有页面、组件、store action 都得记得用你封装的 request,而不是直接写 uni.request」——漏一处,拦截逻辑就断了。建议在 ESLint 中加自定义规则,禁止直接调用 uni.request。这不是功能问题,是工程约束问题。


















