共计 1462 个字符,预计需要花费 4 分钟才能阅读完成。
从踩坑案例说起
最近在开发一个多选批量删除功能时,遇到了一个典型的数组参数传递问题。前端通过 AJAX 发送选中的 ID 数组到 PHP 后端,代码看似简单:

$.ajax({
url: '/delete',
data: {ids: [1, 2, 3] }
})
但后端 $_GET['ids'] 拿到的却是字符串 "1,2,3",不得不手动explode 处理。这种隐式类型转换在 PHP 中很常见,但不符合我们的预期。
参数编码的底层原理
1. Content-Type 的两种选择
- application/x-www-form-urlencoded(默认)
- 将数据编码为 Query String(查询字符串)格式
- 数组参数会变成
ids[]=1&ids[]=2的重复 key 形式 -
需要后端框架支持数组解析(如 PHP 需参数名带
[]) -
application/json
- 直接发送 JSON 字符串
- 保持数据结构完整性
- 需要后端显式解析 JSON
2. 三种主流方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| URLSearchParams | 浏览器原生支持 | 不支持嵌套数据结构 |
| FormData | 支持文件上传 | 需要手动处理数组字段 |
| JSON.stringify | 数据结构保持最完整 | 需要设置 Content-Type |
实战代码演示
前端发送方案
方案 1:URLSearchParams(适合简单数组)
const params = new URLSearchParams()
[1, 2, 3].forEach(id => params.append('ids', id))
fetch('/api', {
method: 'POST',
body: params
})
方案 2:JSON 序列化(推荐)
// axios 示例
axios.post('/api', {ids: [1, 2, 3],
nested: {data: ['a', 'b'] }
}, {headers: { 'Content-Type': 'application/json'}
})
后端接收示例
Spring Boot(Java)
@PostMapping("/api")
public ResponseEntity<?> handleRequest(@RequestBody Map<String, Object> payload) {List<Integer> ids = (List<Integer>) payload.get("ids");
// 处理逻辑
}
Express(Node.js)
app.post('/api', (req, res) => {
const ids = req.body.ids // 需要 body-parser 中间件
// 确保安装了 express.json()})
避坑指南
- URL 长度限制
- IE8: 2083 字符
- Chrome: 8182 字符
-
解决方案:POST+Body 替代 GET
-
特殊字符处理
- 使用
encodeURIComponent处理单个值 -
JSON 方案自动处理编码
-
对象数组处理
// 正确序列化对象数组 const data = { users: [{ id: 1, name: 'Alice'}, {id: 2, name: 'Bob'} ] } // 必须设置 Content-Type
延伸思考
在设计 RESTful API 时,批量操作通常有以下方案:
-
ID 数组方案
DELETE /articles?ids=1,2,3 -
批量请求体方案
POST /batch { "ops": [{ "method": "DELETE", "path": "/articles/1"}, {"method": "PATCH", "path": "/articles/2"} ] } -
自定义端点方案
POST /articles/batch-delete
每种方案各有适用场景,你的选择是?
正文完
