laravel 正确返回 json 需用 api 中间件替代 web、禁用 csrf 或白名单例外、前端通过 header 传 x-csrf-token、捕获异常避免渲染视图、配置 cors 支持跨域,并清除缓存确保配置生效。

怎么让 Laravel 正确返回 JSON 而不是重定向或视图
Laravel 默认把 AJAX 请求当普通请求处理,Auth::user() 未登录时会跳转到 /login,导致前端收到 302 响应而非预期的 JSON。核心是告诉 Laravel “这是 API 场景”,别走 Web 中间件栈。
- 在路由定义时用
Route::middleware('api')替代web,避免 session、CSRF、重定向中间件干扰 - 控制器方法里别用
redirect()或view(),统一用response()->json()或直接return ['data' => ...] - 如果必须复用 Web 路由(比如管理后台),手动禁用 CSRF 验证:在
app/Http/Middleware/VerifyCsrfToken.php的$except数组里加路径,如'api/user/update'
Laravel 的 CSRF token 怎么传给 AJAX 请求
Web 路由默认校验 _token,但 AJAX 不自动带这个字段,直接发 POST/PUT/DELETE 会报 TokenMismatchException。
- 前端从 meta 标签取 token:
document.querySelector('meta[name="csrf-token"]').getAttribute('content') - 全局配置 axios:
axios.defaults.headers.common['X-CSRF-TOKEN'] = token;fetch 则需手动加headers: { 'X-CSRF-TOKEN': token } - 别把 token 放 query string 或 body 里传——
axios.post('/user', { _token: token, name: 'x' })无效,Laravel 只认 header 中的X-CSRF-TOKEN或 form-data 中的_token
为什么 response()->json() 返回的是 HTML 页面
常见于开发环境开启调试模式(APP_DEBUG=true)且返回了异常,Laravel 会渲染错误页面而不是 JSON。这不是 JSON 返回逻辑错了,而是异常没被正确捕获。
- 检查是否在 JSON 响应路径中抛出了未 catch 的异常,比如数据库查询失败、模型找不到——这些会触发 Exception Handler 渲染视图
- 确保控制器里做了基础兜底:
try { ... } catch (\Exception $e) { return response()->json(['error' => '操作失败'], 500); } - 验证响应头:用浏览器 DevTools 看 Network → Response Headers →
Content-Type是否为application/json;不是的话,说明中间件或异常流程劫持了响应
Vue/React 项目里调用 Laravel API 报 CORS 错误
前端运行在 http://localhost:5173,Laravel 后端在 http://localhost:8000,浏览器直接拦截跨域请求,控制台显示 No 'Access-Control-Allow-Origin' header。
- 装官方包:
composer require fruitcake/laravel-cors,它比手写中间件更可靠,支持预检请求(OPTIONS)和动态 origin 白名单 - 发布配置后,在
config/cors.php里设'allowed_origins' => ['http://localhost:5173'],别用['*'](cookie 认证下无效) - 确认中间件已注册:检查
app/Http/Kernel.php的$middlewareGroups['api']是否包含\Fruitcake\Cors\HandleCors::class
真正麻烦的从来不是写个 response()->json(),而是你改了路由中间件,忘了清 config 缓存;或是前端漏传 token,后端又没做友好提示——这些细节卡住的时间,远多于写逻辑本身。










