Axios 中 params 与 data 的区别与原理

Axios 中 params 与 data 的区别与原理

一、核心区别

Axios 中 params 和 data 决定参数放在 HTTP 请求的不同位置:

配置 参数位置 实际效果 适用场景
params URL 查询字符串(Query String) POST /xxx?foo=1&bar=2 传少量简单参数,如 ID、分页、筛选条件
data 请求体(Request Body) Body 中发送 JSON:{"foo":1,"bar":2} 传复杂对象、列表、批量数据

二、具体示例

实际代码对比

ts 复制代码
// 写法一:参数拼到 URL 上
export function printSkuPackageCodeList(data: any) {
  return request({
    url: '/api/save',
    method: 'post',
    params: data,   // data 的内容会被拼到 URL ?key=value
  });
}

// 写法二:参数放到请求体里
export function sampleBuyOrderPrint(params: any) {
  return request({
    url: '/api/save',
    method: 'post',
    data: params,   // params 的内容会作为 JSON Body 发送
  });
}

关键点:函数入参名叫 data 还是 params 不重要,真正决定参数位置的是 request 配置对象的 params 和 data 字段。

Axios 混合使用示例

js 复制代码
axios.post('/api/users',
  { name: 'Alice' },       // 这是 data,放请求体
  { params: { page: 1 } }  // 这是 params,拼 URL
)

实际发出的请求:

http 复制代码
POST /api/users?page=1
Content-Type: application/json

{
  "name": "Alice"
}

三、底层原理

第一层:HTTP 协议层

一个 POST 请求由三部分组成:

http 复制代码
POST /api/print?id=1 HTTP/1.1
Content-Type: application/json

{
  "skuCode": "A001"
}
  • ?id=1 是 URL 查询参数(由 Axios params 控制)
  • { "skuCode": "A001" } 是请求体 Body(由 Axios data 控制)
  • HTTP 协议允许二者同时存在

第二层:Axios 内部处理

Axios 内部对 params 和 data 走两条不同的处理流水线:

js 复制代码
// params -> 拼接到 URL
url = buildURL(url, params, paramsSerializer)
// 结果:/api/xxx?page=1&size=10

// data -> 放进请求体
if (typeof data === 'object') {
  data = JSON.stringify(data)
  headers['Content-Type'] = 'application/json'
}
xhr.send(data)
  • params 经过 buildURL + paramsSerializer 变成 ?key=value
  • data 经过 transformRequest 变成 JSON / FormData / URLSearchParams,再交给 xhr.send()

第三层:浏览器底层

Axios 最终调用的是浏览器的 XMLHttpRequest 或 Fetch API:

js 复制代码
const xhr = new XMLHttpRequest()
xhr.open('POST', url)   // url 已包含 params 拼接的 ?key=value
xhr.send(body)           // body 就是 data 处理后的结果

本质总结:

复制代码
params -> 影响 URL(xhr.open 的第二个参数)
data   -> 影响 Body(xhr.send 的参数)

四、data 的自动序列化机制(transformRequest)

data 不是简单的原样发送,Axios 内部有 transformRequest 处理链:

data 类型 处理方式 默认 Content-Type
普通对象 {} JSON.stringify() application/json
FormData 原样传递 multipart/form-data(浏览器自动设置 boundary)
URLSearchParams 转为 key=value&... application/x-www-form-urlencoded
string 原样传递 text/plain
ArrayBuffer 原样传递 由调用方指定

五、后端如何对应

后端框架 接收 params 接收 data
Spring Boot @RequestParam / getParameter() @RequestBody
Express.js req.query req.body
Django request.GET request.POST / json.loads(request.body)
Go r.URL.Query() json.NewDecoder(r.Body)

六、最佳实践

  1. 看接口文档选择 :文档写 @RequestParam 用 params;写 @RequestBody 用 data
  2. POST 请求优先用 data:绝大多数 POST 接口是提交业务数据,参数应放在请求体
  3. params 适合"路由/过滤"语义 :分页 page/size、状态 status=active、ID 等简单标识
  4. data 适合"提交/创建"语义:表单数据、对象创建、批量操作
  5. 二者可以共存 :如 params 传分页参数,data 传查询条件

七、常见踩坑

坑 1:POST + params 后端收不到数据

ts 复制代码
// 错误:后端用 @RequestBody 接收,但参数被拼到了 URL
request({ url: '/api/save', method: 'post', params: { name: 'test' } })

// 正确:参数应放请求体
request({ url: '/api/save', method: 'post', data: { name: 'test' } })

坑 2:变量名误导

ts 复制代码
// 入参叫 data,但实际走的是 params(拼 URL),容易误判
function api(data) { return request({ url: '...', params: data }) }

建议 :保持命名一致性------走 params 时入参命名为 query 或 queryParams;走 data 时命名为 body 或 payload。

相关推荐
isha1 小时前
Univer拆解——从类与方法的视角分析
前端·javascript
变与不变8061 小时前
GET请求知识详解
前端·javascript
哎哟喂呢哈4 小时前
VedioJS 10
javascript·html5
夏幻灵11 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
三天不学习12 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs1940513 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
小宋102118 小时前
A2UI从零实战:Agent安全生成交互界面与事件回传
javascript·人工智能·安全·交互
大包子18 小时前
structuredClone vs lodash.cloneDeep:核心差异与选型指南
javascript·vue.js
lerhxx19 小时前
AI 应用中的上下文管理 —— 从"上下文窗口"到"分层压缩"的工程实践
前端·javascript