Laravel怎么处理AJAX请求_Laravel前后端交互教程【响应】

1次阅读

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

Laravel怎么处理AJAX请求_Laravel前后端交互教程【响应】

怎么让 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')
  • 全局配置 axiosaxios.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'] 是否包含 FruitcakeCorsHandleCors::class

真正麻烦的从来不是写个 response()->json(),而是你改了路由中间件,忘了清 config 缓存;或是前端漏传 token,后端又没做友好提示——这些细节卡住的时间,远多于写逻辑本身。

text=ZqhQzanResources