API路由必须用Route::apiResource()或Route::post()显式声明并注册在routes/api.php中,避免混入web路由;返回JSON须用response()->json()并配置正确中间件、请求头与模型隐藏字段。

API路由必须用 Route::apiResource() 或 Route::post() 等显式声明
默认的 Route::get() 会走网页渲染逻辑,哪怕你返回 response()->json(),中间件也可能注入 HTML 头、触发 session 启动或 CSRF 验证——这是 API 接口返回空白页或 419 错误最常见的原因。
- API 路由必须注册在
routes/api.php中,它自带api中间件组(含throttle、bindings,但**不包含web中的start_session和verify_csrf_token) - 不要在
routes/web.php里写 API 路由,哪怕加了->middleware('api')也不保险——中间件加载顺序和请求生命周期已不同 - 如果要用资源路由,优先选
Route::apiResource('posts', PostController::class),它自动排除create和edit这两个 HTML 页面方法
response()->json() 是最稳的返回方式,别依赖 return []
Laravel 的自动 JSON 转换(比如直接 return ['data' => $user])只在控制器方法被认定为“API 上下文”时才生效。而这个判断依赖路由是否属于 api 中间件组 + 请求头是否含 Accept: application/json。一旦前端发的是普通表单请求或 curl 不带头,就可能退化成 HTML 响应。
- 显式调用
response()->json($data, $status, $headers, JSON_UNESCAPED_UNICODE),避免中文变 \uXXXX - 状态码别硬写数字,用常量更安全:比如
response()->json($data, 201)改成response()->json($data, Response::HTTP_CREATED)(需 useIlluminate\Http\Response) - 如果要统一包装结构(如
['success' => true, 'data' => ...]),别在每个接口里重复写,改用 API Resource 或全局响应宏
模型数据转 JSON 前,注意 $casts、$appends 和隐藏字段
直接 return response()->json($user) 看似简单,但 $user->toArray() 会把所有可访问属性(包括 $appends、$casts 处理后的值)一股脑吐出去,容易泄露敏感字段(比如 password_hash、remember_token)或引发序列化错误(如 Closure、resource 类型)。
- 在模型里明确设置
protected $hidden = ['password', 'remember_token'],比在控制器里unset()更可靠 - 日期字段若没配
$casts = ['created_at' => 'datetime'],JSON 里会是字符串而非 ISO8601 格式;配合$dateFormat = 'Y-m-d\TH:i:s.v\Z'可控制精度 - 需要动态计算字段(如
is_admin)?用$appends = ['is_admin']+getIsAdminAttribute(),但记得检查该属性是否真被需要——前端未必用得上
调试时看 Content-Type: application/json 和真实响应体,别只信浏览器地址栏
浏览器直接访问 API 路由(比如 /api/users)会触发重定向或 HTML fallback,看起来像 404 或白屏,但这不代表接口坏了。真实问题往往藏在响应头和原始 body 里。
- 用
curl -I http://localhost:8000/api/users查Content-Type是否为application/json;用curl -H "Accept: application/json" http://localhost:8000/api/users模拟正确请求头 - Postman 或
httpie更方便:运行http :8000/api/users,它默认带Accept: application/json - 如果返回
"message": "Unauthenticated.",不是代码错了,是漏了auth:sanctum中间件或 token 没传——检查请求头Authorization: Bearer xxx


















