uni.addInterceptor('request')不是真正请求拦截器,无法修改参数或响应、统一处理401等逻辑;必须手动封装uni.request函数,控制请求前(如拼接URL、注入token)和响应后(如错误分类、跳登录)全流程。

uni.addInterceptor 只能拦截部分 API(如 request、navigateTo),但**它不是真正的请求拦截器**——不能修改 uni.request 的参数或响应结构,也不能统一处理 401、超时、loading 等逻辑。真正可用的“请求拦截器”,必须靠手动封装 uni.request 实现。
为什么 uni.addInterceptor('request', {...}) 不够用
它只在 uni.request 调用前/后触发钩子,但:
• invoke 中改 args.url 或 args.header 不会生效(uni-app 内部不读取你改后的对象);
• success/fail 钩子里拿到的是原始响应,无法统一拦截 401 并跳登录页;
• 多个拦截器之间无执行顺序控制,容易覆盖;
• H5 平台下部分钩子可能不触发,小程序和 App 行为也不一致。
必须手动封装一个 request 函数
所有网络请求都走你写的这个函数,才能真正控制发起前和响应后逻辑:
- 请求前:拼接
baseUrl、注入Authorization、显示 loading、校验 token 是否过期 - 响应后:隐藏 loading、判断
statusCode、对 401/403 清缓存 +uni.reLaunch跳登录、对业务错误码统一 reject - 错误不吞:Promise.reject 后,调用方必须
.catch(),否则静默失败
示例(精简版,可直接用):
export function request(options) {
const baseUrl = 'https://api.example.com'
const token = uni.getStorageSync('token')
// 请求前处理
const config = {
...options,
url: options.url.startsWith('http') ? options.url : baseUrl + options.url,
header: {
...options.header,
Authorization: token ? `Bearer ${token}` : ''
}
}
return new Promise((resolve, reject) => {
uni.request({
...config,
success: (res) => {
// 响应后处理
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res.data)
} else if (res.statusCode === 401) {
uni.removeStorageSync('token')
uni.reLaunch({ url: '/pages/login/login' })
reject(new Error('登录已过期'))
} else {
reject(new Error(res.data?.message || '请求失败'))
}
},
fail: (err) => {
uni.showToast({ title: '网络异常', icon: 'none' })
reject(err)
}
})
})
}
uni.addInterceptor 还能用在哪
它适合做轻量级、非侵入式干预,比如:
- 路由跳转前记录埋点:
uni.addInterceptor('navigateTo', { invoke(args) { console.log('跳转', args.url) } }) - 上传前统一加签名:
uni.addInterceptor('uploadFile', { invoke(args) { args.formData.sign = getSign() } }) - 全局禁用某类 API(返回 false 阻止执行)
注意:uni.removeInterceptor('request', { invoke: fn }) 必须传入**同一函数引用**,匿名函数或箭头函数每次都是新引用,移除会失败。
第三方库如 @escook/request-miniprogram 怎么配
它本质也是封装 uni.request,只是帮你写好了拦截器链。配置关键点:
- 安装后在
main.js中挂载:uni.$http = $http - 设置
$http.baseUrl和$http.beforeRequest/$http.afterRequest - 它不支持
interceptors.request.use那种 Axios 风格的多层链式注册,只有两个钩子 - 云函数调用(
uniCloud.callFunction)需单独封装,它不接管
真正复杂的场景(比如 token 自动刷新、多级错误重试、请求取消),还是得自己写类或用 luch-request 这类更成熟的封装库——但记住,底层永远是绕不开手动封装 uni.request 这一步。


















