uni-app 中应通过封装 request 函数统一处理 baseurl、token、header、错误拦截等逻辑,避免使用不跨端的 uni.interceptors;上传文件需单独封装 upload 函数,与 request 平行且共享基础配置。

uni-app 里怎么用 uni.request 封装统一请求函数
直接封装 uni.request 是最轻量、最可控的方式,不依赖第三方库,也避免 H5/小程序平台兼容性翻车。关键不是“套一层”,而是把重复逻辑收口:基础 URL、超时、默认 header、错误统一处理。
常见错误是把 token 拼在 url 里传,或在 success 回调里手动判状态码——这会让每个接口都重复写相同逻辑。
- 用
uni.getStorageSync('token')同步读取本地 token,避免异步取不到导致 header 缺失 - 所有请求默认加
Content-Type: application/json,但上传文件时必须删掉,否则小程序会静默失败 - 用
...options展开传参,保留原生uni.request所有参数(如sslVerify、withCredentials) - 响应拦截放在
success和fail外层,统一处理 401、500 等业务状态码,而不是只看网络是否通
function request(options) {
const baseUrl = 'https://api.example.com';
const token = uni.getStorageSync('token');
return new Promise((resolve, reject) => {
uni.request({
...options,
url: baseUrl + options.url,
header: {
'Content-Type': 'application/json',
'Authorization': token ? `Bearer ${token}` : '',
...options.header
},
success: (res) => {
if (res.statusCode >= 200 && res.statusCode {
reject(new Error(err.errMsg || '网络异常'));
}
});
});
}
uni-app 请求拦截器怎么配才真正生效
uni-app 没有内置的“拦截器”概念,所谓拦截器其实是靠封装函数+全局变量模拟出来的。很多人以为配个 beforeRequest 就能改请求,结果发现上传文件、WebSocket 或 uni.uploadFile 完全不走这个逻辑——因为它们压根不调用 uni.request。
真正能拦截的,只有你主动调用封装后的 request() 函数的地方。所以拦截点必须落在函数内部,而不是某个配置项里。
-
uni.showLoading和uni.hideLoading放在封装函数开头/结尾最稳妥;放外面容易漏掉并发请求 - 需要动态修改 header(比如某次请求要加 traceId),只能通过
options.custom透传字段,在封装函数里识别并注入 - 不要在拦截逻辑里做异步操作(如先查缓存再发请求),Promise 链会断,建议用单独的缓存策略函数替代
- 小程序真机调试时,
fail中的err.errMsg可能是request:fail net::ERR_CONNECTION_REFUSED,这种属于网络层错误,无法被业务状态码逻辑覆盖
为什么 uni.interceptors 在 H5 下不工作
因为 uni.interceptors 是 uni-app 为 App 平台(iOS/Android)提供的原生层拦截能力,H5 和小程序平台根本不支持该 API。你在 H5 控制台打日志,会看到 uni.interceptors is not a function。
有人试图用条件编译 #ifdef H5 切换逻辑,但这样会导致多端行为不一致——比如 App 端走原生拦截,H5 走 JS 封装,token 刷新时机可能错位。
- 跨端项目一律放弃
uni.interceptors,只用 JS 封装函数作为唯一入口 - 如果必须用原生能力(如 App 端自动注入证书),需在封装函数里判断平台:
uni.getSystemInfoSync().platform === 'app' - H5 下若需更底层控制(如复用 axios 的拦截器语法),可引入 axios,但要自行处理
uni.downloadFile、uni.uploadFile等非 HTTP 方法的兼容
上传文件时 uni.uploadFile 怎么和 token、拦截逻辑对齐
uni.uploadFile 和 uni.request 是两套独立 API,header 写法不同、错误结构不同、甚至返回字段名都不同(比如没有 statusCode,只有 data 字符串)。硬塞进同一个封装函数只会让逻辑越来越乱。
正确做法是提供一个平行的 upload() 函数,共享基础配置(如 base url、token 读取、loading 控制),但保留各自参数签名。
-
uni.uploadFile的header不支持Content-Type,设了会被忽略,且必须用FormData方式传参(实际是小程序自己拼的) - 响应体是字符串,需手动
JSON.parse(res.data),且服务端必须返回标准 JSON,否则会抛语法错误 - 上传进度用
onProgressUpdate,不能用 Promise.then,得单独处理 loading 和错误提示 - 如果上传接口也要鉴权,token 必须写在
header里(小程序支持),而不是 query 参数中
复杂点在于:token 过期重试机制、大文件分片、断点续传这些,已经超出 uni-app 原生能力范围,得自己设计状态管理和降级策略。











