$request->all() 拿不到 json 数据,因为它只解析 application/x-www-form-urlencoded 和 multipart/form-data 请求体;json 请求需用 $request->json()->all(),且必须带 content-type: application/json 头。

为什么 $request->all() 拿不到 JSON 数据
因为 $request->all() 只解析 application/x-www-form-urlencoded 和 multipart/form-data 类型的请求体,而 JSON 请求的 Content-Type 是 application/json,Laravel 默认不自动解析它。此时 $request->input()、$request->post() 全部返回空,但请求体其实完整存在——只是没被解码。
$request->json()->all() 是最稳妥的接收方式
这是 Laravel 官方为 JSON 请求设计的专用接口,内部会检查 Content-Type 是否匹配、调用 json_decode($raw, true),并缓存结果,后续多次调用不会重复解析。
- 必须确保请求头带
Content-Type: application/json,否则$request->json()返回空的ParameterBag - 如果前端发的是 JSON 字符串但漏了 header,
$request->json()->all()会返回[],不是报错,容易误判 - 支持点号访问嵌套字段:
$request->json('user.name')、$request->json('items.*.id') - 和
$request->input()行为一致:未传字段返回null,不抛异常
手动解析 $request->getContent() 的适用场景
仅在以下情况才需要绕过 json() 方法:原始 JSON 需要保留对象结构(而非数组),或要捕获 JSON 解析错误做自定义处理。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
-
$raw = $request->getContent()获取原始字符串,注意它只能读一次(PHP stream 特性) - 必须显式检查
empty($raw),空请求体时json_decode会返回null,不是空数组 - 推荐加错误处理:
$data = json_decode($raw, true); if (json_last_error() !== JSON_ERROR_NONE) { abort(400, 'Invalid JSON'); } - 不要用
file_get_contents('php://input')—— Laravel 的getContent()已做了 SAPI 兼容封装,更可靠
别踩这些坑
常见错误不是“接不到”,而是“以为接到了但逻辑跑偏”:
- 用
$request->all()或$request->input('xxx')直接取 JSON 字段,永远为空 —— 它们不走 JSON 解析路径 - Postman 测试时只填 body 为 raw JSON,但忘了切到
application/json类型,header 仍是默认的text/plain - 前端用
fetch发送 JSON 但没设headers: {'Content-Type': 'application/json'},导致 Laravel 当作普通 POST 处理 - 在 FormRequest 验证类里写
$this->input('xxx'),同样无效;应改用$this->json('xxx')或重写all()方法
JSON 请求体的解析逻辑是“有 header 才触发”,没有商量余地。header 错了,再标准的 JSON 字符串也进不了 json() 分支。










