uni.request 的 header 键名必须全小写,否则 h5 平台可能静默丢弃;带自定义 header 会触发 options 预检,服务端须正确配置 access-control-allow-headers 才能生效。

直接在 uni.request 的 header 对象里写,但必须注意平台差异和预检机制——H5 上最容易“看似写了却没发出去”。
uni.request 的 header 字段名必须全小写
uni-app 要求 header 对象的键名是小写的,比如 'authorization'、'content-type'、'tenant-id'。写成 'Authorization' 或 'Content-Type' 在 H5 和小程序中都可能被忽略(尤其 H5 下部分浏览器会静默丢弃)。
正确写法示例:
uni.request({
url: 'https://api.example.com/user',
method: 'GET',
header: {
'authorization': 'Bearer ' + uni.getStorageSync('token'),
'content-type': 'application/json',
'tenant-id': 'abc123'
}
})
- 大小写敏感是 uni-app 框架层的硬性约定,不是浏览器行为
- 小程序和 App 平台对大小写容忍度略高,但为了一致性,全部统一用小写
- 如果用了大写,在 H5 控制台 Network 面板里点开请求,
Request Headers区域根本看不到你写的字段
H5 平台下带自定义 header 必然触发 OPTIONS 预检
这是最常被误判为“uni-app bug”的地方:你在 H5 上写了 'authorization',但 Network 面板里真实请求没发出,或者控制台报 CORS 错误,大概率是服务端没正确响应预检请求。
- 浏览器对含自定义 header(如
authorization、tenant-id)的跨域请求,会自动先发一次OPTIONS请求 - 这个预检请求不带任何你写的
header,只带Origin和Access-Control-Request-Headers - 服务端必须返回:
Access-Control-Allow-Headers: authorization, tenant-id, content-type(显式列出你用到的 header) - 否则后续真实请求被浏览器拦截,连发都发不出去
- App 和小程序不走 CORS,所以同一套代码在它们上面正常,容易掩盖问题
如何统一加 header 而不每个请求都手写
推荐用 uni.addInterceptor,它是 uni-app 官方支持的拦截机制,比手动封装 uni.request 更可靠、更易维护。
示例:在 main.js 中添加全局请求拦截器
uni.addInterceptor('request', {
invoke(args) {
const noAuthUrls = ['/login', '/public/info']
const isNoAuth = noAuthUrls.some(url => args.url.includes(url))
if (!isNoAuth) {
const token = uni.getStorageSync('token')
args.header = {
...args.header,
'authorization': token ? `Bearer ${token}` : '',
'content-type': 'application/json'
}
}
}
})
-
invoke是唯一能修改args的钩子,success/fail都是只读回调 - 务必用展开运算符
...args.header保留原有 header,避免覆盖掉content-type等基础字段 - 白名单逻辑要放在拦截器里做,而不是每个接口单独判断
- 不要在拦截器里做异步操作(如刷新 token),那需要额外封装 Promise 链,
invoke必须同步返回
用 axios 替代 uni.request 时 header 设置方式不同
如果你项目里用了 axios(比如通过 npm install axios 引入),它的 header 设置规则和 uni.request 完全无关,走的是标准 axios 流程。
- 必须用
instance.defaults.headers.common或interceptors.request.use设置 - 键名大小写不敏感(axios 内部会 normalize),但建议仍用小写保持习惯一致
- 同样受 H5 CORS 限制,服务端仍需正确配置
Access-Control-Allow-Headers - 注意:uni-app 的
uni.$u.http(uView 封装)也是基于uni.request,不是 axios,别混用概念
真正容易被忽略的点是:header 生效与否,80% 取决于服务端是否配合处理预检;剩下 20% 才是客户端写法。调试时先看 Network 面板里有没有 OPTIONS 请求,再确认它的响应头里有没有你想要的 Access-Control-Allow-Headers 字段。











