API 请求头 Header 配置教程:Authorization、Content-Type 写法与 401/415 排错

调用 API 时,很多问题不是接口本身坏了,而是请求头 Header 没配对。

最常见的两个 Header 是:

  • Authorization:告诉服务器"我是谁、有没有权限"
  • Content-Type:告诉服务器"我提交的 Body 是什么格式"

如果这两个字段写错,经常会遇到:

  • 401 Unauthorized
  • 403 Forbidden
  • 415 Unsupported Media Type
  • 后端收不到参数
  • Postman 能通,浏览器代码不通

这篇按实际配置流程讲清楚:Header 写在哪里、Authorization 怎么填、Content-Type 怎么选,以及在 Postman、Apifox、curl、fetch、Axios 里如何验证。


1. 一个完整 API 请求长什么样?

先看一个典型的 POST JSON 请求:

复制代码
POST /users HTTP/1.1
Host: api.example.com
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
Accept: application/json

{"name":"Tom","age":18}

可以把它拆成三部分:

复制代码
请求行:POST /users HTTP/1.1
请求头:Authorization、Content-Type、Accept
请求体:{"name":"Tom","age":18}

也就是说:

  • POST /users 表示请求方法和接口路径
  • AuthorizationContent-TypeAccept 是 Header
  • 最后一行 JSON 是 Body,也就是提交的数据

一个很重要的原则:

Header 放请求元信息,不放业务参数。

例如:

  • 用户名、年龄、订单号:通常放在 URL Query 或 Body
  • Token、Body 格式、期望返回格式:通常放在 Header

不要把业务 JSON 参数塞进 Header。


2. Header 的基本写法

HTTP Header 本质上是一组键值对:

复制代码
Header-Name: Header Value

常见写法:

复制代码
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
Accept: application/json

写 Header 时建议遵守这些规则:

  1. Header 名通常不区分大小写,但建议使用常见写法

    例如 Content-TypeAuthorization

  2. 多个 Header 分多行写

    不要把多个 Header 硬拼成一行

  3. Header 是元信息,不是 Body

    不要把 JSON 参数写到 Header 里

  4. 以接口文档为准

    文档要求传 X-API-Key,就不要擅自改成 Authorization

不同工具中的位置如下:

工具 Header 配置位置
Postman / Apifox Headers 表格
curl -H 参数
JavaScript fetch headers 对象
Axios 请求配置里的 headers
环境变量方式 代码里读取 API_TOKENAPI_BASE_URL 等变量后写入 Header

3. Authorization 请求头怎么写?

Authorization 用于鉴权。

它的作用可以理解为:

告诉服务端:当前请求是谁发起的,是否有权限访问这个接口。

最常见的写法是 Bearer Token:

复制代码
Authorization: Bearer YOUR_TOKEN

这里要注意几个细节:

  • Bearer 和 token 中间必须有一个空格
  • YOUR_TOKEN 要替换成真实 token
  • 通常不要写成 Bearer <abc123>,除非文档明确要求带尖括号
  • 不要复制多余的引号、换行符、前后空格
  • 不要把 token 放到 URL 查询参数里

错误示例:

复制代码
Authorization: BearerYOUR_TOKEN

问题:Bearer 后面缺少空格。

错误示例:

复制代码
Authorization: "Bearer YOUR_TOKEN"

问题:有些接口会把引号也当成 Header 值的一部分。

推荐写法:

复制代码
Authorization: Bearer abc123

4. 常见鉴权 Header 类型

不同平台的鉴权方式不完全一样,并不是所有接口都使用 Authorization: Bearer xxx

类型 示例 常见场景
Bearer Token Authorization: Bearer xxx OAuth2、JWT、登录后访问接口
Basic Auth Authorization: Basic base64(username:password) 简单账号密码认证、内部系统
API Key Header X-API-Key: xxx 开放平台、第三方 API
签名认证 Authorization: 签名结果 云厂商 API、金融类 API

有些接口文档可能要求:

复制代码
X-API-Key: YOUR_API_KEY

或者:

复制代码
Token: YOUR_TOKEN

这种情况下不要自行改成:

复制代码
Authorization: Bearer YOUR_API_KEY

除非文档明确支持。

签名认证也要特别注意。某些云厂商或企业接口会把签名结果放到 Authorization 中,但它和普通 Bearer Token 不是一回事。

签名认证通常还会涉及:

  • 时间戳
  • 请求路径
  • 请求方法
  • Body 哈希
  • Secret Key
  • 签名算法

不能只复制一个 Header 就认为完成鉴权,需要按对应接口文档生成签名。


5. Content-Type 请求头怎么写?

Content-Type 用来说明请求 Body 的格式。

例如 Body 是 JSON:

复制代码
{"name":"Tom","age":18}

那么 Header 应该写:

复制代码
Content-Type: application/json

常见对应关系如下:

Body 类型 Content-Type 常见场景
JSON application/json REST API 中常见的 POST / PUT
表单键值对 application/x-www-form-urlencoded 登录表单、传统表单提交
文件上传 multipart/form-data 上传图片、上传文件
纯文本 text/plain 发送纯文本
XML application/xmltext/xml 老系统、企业接口

判断原则很简单:

Body 是什么格式,Content-Type 就写什么格式。

例如你发送的是 JSON:

复制代码
{"name":"Tom","age":18}

就写:

复制代码
Content-Type: application/json

如果发送的是表单:

复制代码
username=tom&password=123456

就写:

复制代码
Content-Type: application/x-www-form-urlencoded

不要 Body 是表单,却写:

复制代码
Content-Type: application/json

否则后端可能解析不到参数。


6. GET 请求需要 Content-Type 吗?

通常不需要。

因为 Content-Type 描述的是请求 Body 的格式,而 GET 请求一般没有 Body。

例如:

复制代码
GET /users?id=1 HTTP/1.1
Host: api.example.com
Authorization: Bearer YOUR_TOKEN

这种请求通常不需要:

复制代码
Content-Type: application/json

很多新手会给所有请求都加上 Content-Type: application/json,大多数时候不一定直接报错,但并不推荐。

原因包括:

  • GET 通常没有 Body,不需要声明 Body 格式
  • 某些接口会对多余 Header 做校验
  • 浏览器环境下,某些 Header 可能触发 CORS 预检

如果接口文档明确要求 GET 也传某个 Header,则按文档来。


7. Content-Type 和 Accept 的区别

Content-TypeAccept 很容易混淆。

它们分别描述两个方向:

复制代码
Content-Type: application/json
Accept: application/json

含义如下:

Header 含义
Content-Type 我发给服务器的数据是什么格式
Accept 我希望服务器返回什么格式

例如提交 JSON,并希望服务端也返回 JSON:

复制代码
Content-Type: application/json
Accept: application/json

如果接口没有特殊要求,很多 API 不写 Accept 也会默认返回 JSON。

但如果文档明确要求:

复制代码
Accept: application/json

建议按文档填写。


8. Postman / Apifox 中如何配置 Header?

在 Postman 或 Apifox 中,进入请求的 Headers 面板,按 Key / Value 填写即可。

示例:

Key Value
Authorization Bearer YOUR_TOKEN
Content-Type application/json
Accept application/json

也可以写成文本理解:

复制代码
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
Accept: application/json

如果你在 Body 中选择了:

复制代码
raw + JSON

Postman 通常会自动添加:

复制代码
Content-Type: application/json

如果你在 Authorization 面板选择了 Bearer Token,也可能自动生成:

复制代码
Authorization: Bearer xxx

所以调试时要检查:

  • 是否重复添加了两个 Authorization
  • 是否重复添加了两个 Content-Type
  • 是否还残留旧 token
  • token 前后是否有空格
  • Header 名是否拼写错误
  • Body 类型是否和 Content-Type 一致

9. curl 中如何添加 Header?

curl 使用 -H 添加请求头。

示例:POST JSON 请求

复制代码
curl -X POST "https://api.example.com/users" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Tom","age":18}'

说明:

  • -X POST 指定请求方法
  • -H 添加 Header
  • -d 指定请求 Body
  • Content-Type 要和 -d 的内容格式一致

如果 -d 是 JSON 字符串:

复制代码
-d '{"name":"Tom","age":18}'

就使用:

复制代码
Content-Type: application/json

如果发送表单键值对:

复制代码
curl -X POST "https://api.example.com/login" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=tom&password=123456"

就不要继续写:

复制代码
Content-Type: application/json

否则后端可能按 JSON 解析,导致参数为空。


10. JavaScript fetch 中如何配置 Header?

fetch 中的 Header 写在 headers 对象里。

示例:

复制代码
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'Tom', age: 18 })
})

重点有四个:

  1. headers 是对象
  2. JSON 请求要设置 Content-Type: application/json
  3. Body 要用 JSON.stringify() 转成 JSON 字符串
  4. 不要把 JavaScript 对象直接塞进 body

错误示例:

复制代码
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: { name: 'Tom', age: 18 }
})

问题在于:

复制代码
body: { name: 'Tom', age: 18 }

这里传的是 JavaScript 对象,不是 JSON 字符串。

推荐写法:

复制代码
body: JSON.stringify({ name: 'Tom', age: 18 })

另外,不建议把生产环境 token 直接硬编码在前端源码里。


11. Axios 中如何配置 Header?

Axios 的 Header 写在请求配置中。

示例:

复制代码
axios.post(
  'https://api.example.com/users',
  { name: 'Tom', age: 18 },
  {
    headers: {
      Authorization: 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  }
)

结构可以理解为:

复制代码
axios.post(url, data, config)

对应关系:

参数 含义
url 请求地址
data 请求 Body
config.headers 请求头

Axios 在发送普通对象时,通常会按 JSON 处理,并设置合适的 Content-Type

不过新手阶段建议先显式写出来,方便理解完整请求结构。

真实项目中,token 通常不会每个接口手写一遍,而是通过请求拦截器统一添加。

示例:

复制代码
axios.interceptors.request.use(config => {
  const token = localStorage.getItem('token')

  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }

  return config
})

需要注意:

  • 前端保存 token 要考虑安全风险
  • 高权限、长期有效的密钥不适合放在前端
  • 需要保护的密钥更适合放在服务端

12. 使用环境变量管理 Token 和 Endpoint

在项目中,不建议把 token、API 地址直接写死在代码里。

更常见的做法是使用环境变量。

例如:

复制代码
API_BASE_URL=https://api.example.com
API_TOKEN=YOUR_TOKEN
API_MODEL=your-model-name

代码中读取后再组装请求:

复制代码
const baseURL = process.env.API_BASE_URL
const token = process.env.API_TOKEN

fetch(`${baseURL}/users`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'Tom', age: 18 })
})

这样做的好处是:

  • 本地、测试、生产环境可以使用不同配置
  • token 不容易散落在业务代码中
  • Endpoint 变更时更容易统一调整
  • 配合部署平台时更容易管理密钥

但要注意:

  • 不要把包含真实 token 的 .env 文件提交到公开仓库
  • 不要在日志中完整打印 Authorization
  • 不要把高权限密钥放在前端构建产物里
  • 具体变量名以项目约定或接口文档为准

13. API Endpoint、模型名和鉴权要分开看

在配置 API 时,很多人会把 Endpoint、模型名、Header 混在一起。

实际排查时建议拆开:

13.1 Endpoint

Endpoint 是请求地址,例如:

复制代码
https://api.example.com/users

它决定请求发到哪里。

常见错误:

  • 域名写错
  • 路径少了版本号
  • 多写或少写 /
  • 把测试环境和生产环境混用

13.2 Authorization

Authorization 决定你有没有权限:

复制代码
Authorization: Bearer YOUR_TOKEN

常见错误:

  • token 为空
  • token 过期
  • Bearer 拼错
  • Bearer 后缺少空格
  • 复制了多余引号或换行符

13.3 Content-Type

Content-Type 决定后端如何解析 Body:

复制代码
Content-Type: application/json

常见错误:

  • JSON Body 配了表单类型
  • 表单 Body 配了 JSON 类型
  • 文件上传时手动乱写 multipart/form-data; boundary=...

13.4 模型名或业务参数

如果某些接口需要模型名、业务类型、用户 ID 等参数,它们通常属于 Body 或 Query,而不是 Header。

例如:

复制代码
{
  "model": "your-model-name",
  "messages": []
}

这类字段是否需要、叫什么名字,应以具体接口文档为准。


14. 文件上传时 Content-Type 怎么处理?

文件上传通常使用:

复制代码
Content-Type: multipart/form-data

但在浏览器、Postman、Axios 这类工具里,很多情况下不建议手动写完整的 Content-Type

原因是文件上传需要 boundary,例如:

复制代码
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxxx

这个 boundary 通常由浏览器或请求库自动生成。

如果你手动写死:

复制代码
Content-Type: multipart/form-data

反而可能导致后端无法正确解析文件。

一般做法是:

  • Postman / Apifox:Body 选择 form-data
  • 浏览器:使用 FormData
  • Axios:传入 FormData,让请求库处理边界

示例:

复制代码
const formData = new FormData()
formData.append('file', file)

axios.post('https://api.example.com/upload', formData, {
  headers: {
    Authorization: 'Bearer YOUR_TOKEN'
  }
})

这里没有手动写 Content-Type,让 Axios 或浏览器自动处理。


15. 常见报错排查:401、403、415

Header 配错后,最常见的报错可以按下面顺序排查。

报错 常见原因 排查方向
401 Unauthorized 没传 token、token 过期、Bearer 格式错误 检查 Authorization
403 Forbidden token 有效但权限不够 检查账号、角色、接口权限
415 Unsupported Media Type Content-Type 不被支持 改成接口文档要求的类型
后端收不到参数 Body 和 Content-Type 不匹配 JSON 配 JSON,表单配表单
CORS 预检失败 自定义 Header 或 Authorization 触发预检 后端允许对应 Header、Method、Origin

16. 401 Unauthorized 怎么排查?

遇到 401 Unauthorized,优先看鉴权。

检查点:

复制代码
Authorization: Bearer YOUR_TOKEN

逐项确认:

  1. 是否真的传了 Authorization
  2. Bearer 是否拼写正确
  3. Bearer 后面是否有空格
  4. token 是否过期
  5. token 是否复制完整
  6. 是否误带了引号、换行、尖括号
  7. 当前接口是否要求的不是 Bearer,而是 X-API-Key

可以先用 curl 验证:

复制代码
curl "https://api.example.com/users" \
  -H "Authorization: Bearer YOUR_TOKEN"

如果 curl 也返回 401,通常说明 token、权限或 Header 格式有问题。

如果 curl 正常,浏览器代码不正常,则继续检查 CORS 或前端请求代码。


17. 403 Forbidden 怎么排查?

403 Forbidden401 不一样。

一般可以这样理解:

  • 401:你是谁,服务端无法确认
  • 403:知道你是谁,但你没有权限

常见原因:

  • 当前账号没有接口权限
  • token 权限范围不够
  • 使用了错误环境的 token
  • 签名权限不足
  • 接口限制了访问来源或角色

排查方式:

  1. 确认 token 对应的账号
  2. 确认账号是否有接口权限
  3. 确认调用的是测试环境还是生产环境
  4. 如果是签名认证,检查签名范围和权限配置

18. 415 Unsupported Media Type 怎么排查?

415 Unsupported Media Type 通常和 Content-Type 有关。

例如接口只支持 JSON:

复制代码
Content-Type: application/json

但你发送了:

复制代码
Content-Type: text/plain

就可能返回 415。

排查步骤:

  1. 查看接口文档要求的 Content-Type
  2. 查看实际请求 Header
  3. 查看 Body 是否和 Header 匹配
  4. 使用 Postman 或 curl 复现
  5. 如果是文件上传,检查是否错误手写了 boundary

JSON 请求推荐组合:

复制代码
Content-Type: application/json

{"name":"Tom","age":18}

表单请求推荐组合:

复制代码
Content-Type: application/x-www-form-urlencoded

name=Tom&age=18

19. Postman 能通,浏览器代码不通怎么办?

这是很常见的问题。

如果 Postman 能请求成功,但浏览器里失败,不一定是 Header 写错,可能是浏览器跨域限制。

尤其当前端请求带有:

复制代码
Authorization: Bearer YOUR_TOKEN

或者自定义 Header:

复制代码
X-API-Key: xxx

浏览器可能会先发送一个 OPTIONS 预检请求。

后端需要正确返回允许信息,例如:

复制代码
Access-Control-Allow-Origin: https://your-frontend.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type

如果后端没有允许 AuthorizationContent-Type,浏览器会拦截请求。

排查思路:

  1. 打开浏览器 DevTools
  2. 查看 Network 面板
  3. 看是否有 OPTIONS 请求失败
  4. 看响应头中是否允许了对应 Header
  5. 后端补充 CORS 配置

注意:

CORS 是浏览器安全机制,Postman 不受同样限制,所以 Postman 能通不代表浏览器一定能通。


20. 安全与最佳实践

Header 配置不仅要能跑通,也要注意安全。

尤其是 Authorization 中的 token,一旦泄露,可能等同于登录态泄露。

建议遵守这些规则:

  1. 不要把 token 放在 URL 中

不推荐:

复制代码
https://api.example.com/users?token=xxx

推荐:

复制代码
Authorization: Bearer YOUR_TOKEN
  1. 不要把真实 token 提交到 GitHub

包括:

  • 源码
  • .env
  • README
  • 示例截图
  • 接口调试记录
  1. 不要在日志中完整打印 Authorization

不推荐:

复制代码
Authorization: Bearer eyJhbGciOi...

可以打码:

复制代码
Authorization: Bearer eyJhbGci...
  1. 尽量使用 HTTPS

token 应该通过 HTTPS 传输,避免明文暴露。

  1. 前端不要保存高权限长期密钥

前端代码最终会暴露给用户,不适合保存高权限、长期有效的密钥。

如果需要保护密钥,更推荐:

复制代码
前端 -> 自己的后端 -> 第三方 API

由服务端保管密钥并转发请求。


21. 新手配置 API Header 的推荐流程

如果你正在接一个新接口,可以按这个流程来:

第一步:确认接口地址

复制代码
https://api.example.com/users

确认:

  • 域名
  • 路径
  • API 版本
  • HTTP 方法

第二步:确认鉴权方式

查看文档要求的是哪一种:

复制代码
Authorization: Bearer xxx

或:

复制代码
X-API-Key: xxx

不要自己猜 Header 名。

第三步:确认 Body 格式

如果 Body 是 JSON:

复制代码
{"name":"Tom","age":18}

就配置:

复制代码
Content-Type: application/json

如果是表单:

复制代码
name=Tom&age=18

就配置:

复制代码
Content-Type: application/x-www-form-urlencoded

第四步:用 Postman 或 curl 先验证

curl 示例:

复制代码
curl -X POST "https://api.example.com/users" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Tom","age":18}'

先保证最小请求能通。

第五步:再迁移到代码中

fetch 示例:

复制代码
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'Tom', age: 18 })
})

Axios 示例:

复制代码
axios.post(
  'https://api.example.com/users',
  { name: 'Tom', age: 18 },
  {
    headers: {
      Authorization: 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  }
)

22. FAQ

22.1 Header 名大小写有影响吗?

HTTP Header 名通常不区分大小写。

也就是说:

复制代码
content-type: application/json

和:

复制代码
Content-Type: application/json

语义上通常是一样的。

但为了可读性和通用习惯,建议写成:

复制代码
Content-Type
Authorization

22.2 token 应该放 Header 还是 URL?

一般建议放 Header:

复制代码
Authorization: Bearer YOUR_TOKEN

不建议放 URL:

复制代码
https://api.example.com/users?token=xxx

因为 URL 更容易出现在:

  • 浏览器历史记录
  • 服务器日志
  • 代理日志
  • 监控系统
  • 截图和分享链接

泄露风险更高。


22.3 可以同时写 Authorization 和 Content-Type 吗?

可以,而且很常见。

例如:

复制代码
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

它们解决的是两个不同问题:

  • Authorization:鉴权
  • Content-Type:说明请求 Body 格式

两者不冲突。


22.4 Content-Type 是 application/json 时,Body 怎么写?

Body 应该是合法 JSON 字符串:

复制代码
{"name":"Tom","age":18}

在 JavaScript 中要这样写:

复制代码
body: JSON.stringify({ name: 'Tom', age: 18 })

不要直接写:

复制代码
body: { name: 'Tom', age: 18 }

两者都可以表示登录态,但机制不同。

Authorization 通常由客户端主动写入 Header:

复制代码
Authorization: Bearer xxx

Cookie 更多用于浏览器会话,浏览器会根据域名自动携带:

复制代码
Cookie: sessionid=xxx

具体使用哪种方式,取决于系统设计和接口文档。


总结

API Header 配置可以先记住三件事:

  1. 需要鉴权时,先看文档要求的是 AuthorizationX-API-Key,还是其他自定义 Header
  2. 只要请求有 Body,就让 Content-Type 和 Body 格式保持一致
  3. 请求失败时,按 401403415 分别排查 token、权限和 Body 类型

对新手来说,不需要一开始背所有 Header 字段。先把 AuthorizationContent-TypeAccept 这几个最常见字段搞清楚,再结合 Postman、curl、fetch、Axios 验证,请求调试会顺很多。