Axios 参数放哪里?一文搞懂 headers、params 和 body
在前端使用 Axios 调接口时,最容易混淆的问题之一就是:一个参数到底应该放在 headers、params,还是请求体 body 中?
这几个位置都能"携带参数",但它们表达的含义不同。放错位置后,常见结果是后端拿不到参数、接口返回参数校验失败,或者敏感信息意外出现在 URL 和日志中。
本文从 HTTP 请求的结构开始,结合 Axios 示例说明每个位置的作用、区别和使用场景。
一、先理解一次 HTTP 请求
可以把一次 HTTP 请求想象成寄快递:
| 请求部分 | 类比 | 主要作用 |
|---|---|---|
| URL | 收件地址 | 指定请求哪个接口 |
| 路径参数 | 地址中的门牌号 | 指定某个具体资源 |
params |
快递单上的查询条件 | 对资源进行查询、筛选或分页 |
headers |
快递单上的附加信息 | 描述请求、携带身份信息 |
body |
包裹里面的内容 | 携带要提交的业务数据 |
一次请求可以同时包含这些部分。例如:
http
POST /api/orders/1001?source=cart HTTP/1.1
Authorization: Bearer token
Content-Type: application/json
{
"quantity": 2,
"remark": "尽快发货"
}
这条请求中:
/api/orders/1001是请求地址,其中1001是路径参数。source=cart是查询参数,也就是 Axios 中的params。Authorization和Content-Type是请求头,也就是headers。- JSON 对象是请求体,也就是
body。
二、headers:请求头
请求头用于描述请求本身,或者携带与请求相关的通用信息。
常见的请求头包括:
js
headers: {
Authorization: 'Bearer token',
'Content-Type': 'application/json',
'Accept-Language': 'zh-CN'
}
Axios 示例:
js
axios.get('/api/user', {
headers: {
Authorization: 'Bearer token'
}
})
适合放在 headers 中的内容:
- 登录凭证,例如
Authorization。 - 请求体格式,例如
Content-Type。 - 希望接收的响应格式,例如
Accept。 - 语言、设备类型、请求追踪 ID 等元信息。
不建议把普通业务字段都塞进自定义请求头。比如商品数量、用户名、搜索关键字等,应根据接口定义放到 params 或请求体中。
关于 Content-Type
当 Axios 发送普通 JavaScript 对象时,通常会自动按 JSON 处理请求体:
js
axios.post('/api/users', {
name: 'Tom',
age: 18
})
大多数情况下不需要手动设置 Content-Type: application/json。是否需要手动设置,应以项目封装方式和后端接口要求为准。
三、params:URL 查询参数
Axios 中的 params 会被拼接到 URL 后面,也叫 Query Parameters。
js
axios.get('/api/users', {
params: {
page: 1,
pageSize: 20,
keyword: 'tom'
}
})
最终请求地址类似于:
text
/api/users?page=1&pageSize=20&keyword=tom
params 适合放:
- 搜索关键字。
- 分页参数,例如
page、pageSize。 - 排序方式。
- 筛选条件。
- 查询选项。
例如:
js
axios.get('/api/orders', {
params: {
status: 'paid',
page: 1
}
})
这通常表示:查询已支付订单,并获取第 1 页数据。
使用 params 时要注意隐私
params 会出现在 URL 中,因此可能被以下位置看到或记录:
- 浏览器地址栏或开发者工具。
- 浏览器历史记录。
- 服务器、代理和网关日志。
- 监控系统或错误上报系统。
所以不要把密码、完整 token、身份证号等敏感信息放到 params 中。
四、body:请求体
HTTP 中的请求体用于携带真正要提交的业务数据。Axios 中通常通过 data 参数传入,它对应的就是请求体。
js
axios.post('/api/users', {
name: 'Tom',
age: 18
})
这里的第二个参数就是 body,发送的数据大致如下:
http
POST /api/users HTTP/1.1
Content-Type: application/json
{
"name": "Tom",
"age": 18
}
请求体适合放:
- 新增数据。
- 修改数据。
- 表单提交。
- 复杂对象和数组。
- 需要提交的大量业务字段。
例如登录请求:
js
axios.post('/api/login', {
username: 'tom',
password: 'password'
})
这里的用户名和密码是登录业务数据,因此放在请求体中。登录成功后,服务端返回的 token 通常在后续请求中放到 Authorization 请求头中。
五、Axios 中最容易混淆的参数位置
GET 请求
Axios 的 GET 请求通常写成:
js
axios.get(url, config)
例如:
js
axios.get('/api/users', {
params: {
page: 1,
keyword: 'tom'
},
headers: {
Authorization: 'Bearer token'
}
})
这里:
params放查询参数。headers放请求头。- 第二个参数整体是 Axios 的配置对象。
POST 请求
Axios 的 POST 请求通常写成:
js
axios.post(url, data, config)
例如:
js
axios.post(
'/api/users',
{
name: 'Tom',
age: 18
},
{
params: {
source: 'admin'
},
headers: {
Authorization: 'Bearer token'
}
}
)
要特别记住:
js
axios.post(
url, // 第一个参数:请求地址
data, // 第二个参数:body,也就是请求体
config // 第三个参数:配置,包含 params 和 headers
)
因此,下面的 name 是 body:
js
axios.post('/api/users', {
name: 'Tom'
})
而下面的 source 是 URL 查询参数:
js
axios.post('/api/users', null, {
params: {
source: 'admin'
}
})
最终 URL 类似于:
text
/api/users?source=admin
六、一个完整的 Axios 请求
js
axios.post(
'/api/orders/1001',
{
quantity: 2,
remark: '尽快发货'
},
{
params: {
source: 'cart'
},
headers: {
Authorization: 'Bearer token'
}
}
)
这条请求可以还原成:
http
POST /api/orders/1001?source=cart HTTP/1.1
Authorization: Bearer token
Content-Type: application/json
{
"quantity": 2,
"remark": "尽快发货"
}
各部分的职责如下:
| Axios 写法 | 最终位置 | 作用 |
|---|---|---|
'/api/orders/1001' |
URL | 指定订单资源 |
params: { source: 'cart' } |
URL 后面 | 说明查询来源 |
headers: { Authorization: ... } |
请求头 | 携带身份凭证 |
| 第二个参数对象 | 请求体 | 提交数量和备注 |
七、params、路径参数和 body 的区别
下面三种写法都可以携带一个 id,但含义不同。
1. 路径参数
js
axios.get('/api/users/100')
最终 URL:
text
/api/users/100
通常表示:获取 ID 为 100 的用户。这里的 100 是 URL 路径的一部分,不是 Axios 的 params。
2. 查询参数
js
axios.get('/api/users', {
params: {
id: 100
}
})
最终 URL:
text
/api/users?id=100
通常表示:在用户集合中按 id=100 查询。
3. 请求体
js
axios.post('/api/users/search', {
id: 100,
includeDeleted: false
})
通常用于复杂查询条件,尤其是查询条件包含嵌套对象、数组或大量字段时。
最终应该采用哪一种,要以接口文档为准。前端不能仅凭"参数名字一样"就随意改变参数位置,因为后端会从不同位置读取参数。
八、文件上传时的 body
文件上传通常使用 FormData,而不是直接发送普通 JSON:
js
const formData = new FormData()
formData.append('file', file)
formData.append('description', '头像')
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
这里:
formData是请求体。- 文件和描述信息都放在请求体中。
- token 仍然通常放在
headers中。 - 额外的查询选项仍然可以放在
params中。
在浏览器环境中,使用 FormData 时通常可以让 Axios 或浏览器自动生成带 boundary 的 Content-Type。如果项目已有统一请求封装,应遵循项目封装的写法,避免手动设置错误的 boundary。
九、如何根据接口文档判断参数放哪里
看到接口文档时,可以按下面的对应关系判断:
| 接口文档中的位置 | Axios 写法 |
|---|---|
| Headers / Request Headers | headers |
| Query / Query Parameters | params |
| Request Body / Body | data,也就是 body |
| Path Parameters | 直接替换或拼接到 URL |
例如接口文档如下:
text
POST /api/user/{userId}
Headers:
Authorization: token
Query:
verbose: true
Body:
{
"name": "Tom",
"age": 18
}
对应的 Axios 写法是:
js
axios.post(
`/api/user/${userId}`,
{
name: 'Tom',
age: 18
},
{
params: {
verbose: true
},
headers: {
Authorization: token
}
}
)
十、常见错误
错误一:把 POST 的 body 写进配置对象
错误示例:
js
axios.post('/api/users', {
headers: {
name: 'Tom'
}
})
这里的 name 并没有放在请求头中,它只是被放进了 headers 配置。正确写法取决于接口要求:
js
axios.post('/api/users', {
name: 'Tom'
})
如果 name 是业务数据,它应该放在第二个参数,也就是 body 中。
错误二:把 params 当成 POST 的 body
js
axios.post('/api/users', {
params: {
name: 'Tom'
}
})
这段代码会把整个对象作为 body 发送,最终 body 是:
json
{
"params": {
"name": "Tom"
}
}
如果想发送真正的查询参数,应写成:
js
axios.post('/api/users', null, {
params: {
name: 'Tom'
}
})
错误三:把敏感信息放进 URL
不要这样写:
js
axios.get('/api/login', {
params: {
username: 'tom',
password: 'password'
}
})
登录信息通常应根据接口定义放到 HTTPS 请求的 body 中:
js
axios.post('/api/login', {
username: 'tom',
password: 'password'
})
HTTPS 可以保护传输过程,但不能改变 URL 可能被日志、历史记录或监控系统保存这一事实。
错误四:只看 HTTP 方法,不看接口文档
很多人认为:GET 只能用 params,POST 只能用 body。这个理解不够准确:
- GET 通常使用
params,但具体仍由接口定义决定。 - POST 既可以有 body,也可以同时有
params和headers。 - 最终应以接口文档约定的参数位置为准。
十一、最后记住这句话
text
headers = 请求说明和身份信息
params = URL 后面的查询条件
body = 要提交的业务内容
在 Axios 中,尤其要记住 POST 的参数顺序:
js
axios.post(url, data, config)
url:请求地址。data:请求体,也就是 body。config:请求配置,其中可以放params和headers。
只要先看接口文档中参数属于 Headers、Query、Body 还是 Path,再对应到 Axios 的写法,就不会再混淆。