Laravel怎么处理CORS跨域_Laravel API跨域配置教程【兼容】

1次阅读

laravel api 跨域失败主因是未正确配置 cors 中间件:需安装 fruitcake/laravel-cors(laravel 9+ 默认集成),并在 kernel.php 的 api 中间件组中注册 handlecors,同时确保 allowed_origins 与 supports_credentials 兼容、中间件顺序正确(尤其 sanctum 场景下需置于 startsession 前)。

Laravel怎么处理CORS跨域_Laravel API跨域配置教程【兼容】

为什么 Laravel API 返回 403 或预检失败

不是你前端写错了,大概率是 Laravel 没配 Cors 中间件,或者配了但没生效。Laravel 默认不处理 OPTIONS 预检请求,浏览器发完 OPTIONS 就卡住,接着拒绝后续 POST/PUT 请求——现象就是控制台报 403 Forbidden 或直接 net::ERR_FAILED

常见错误:只改了 config/cors.php,但忘了在 app/http/Kernel.php 的中间件组里注册 FruitcakeCorsHandleCors::class;或者用的是 Laravel 8+,但装了过时的 barryvdh/laravel-cors(已废弃)。

  • 确认已安装官方维护包:composer require fruitcake/laravel-cors
  • Laravel 9+ 默认已集成,但需检查 app/Http/Kernel.php$middleware 数组是否包含 FruitcakeCorsHandleCors::class
  • 若只对 API 路由生效,确保它放在 $middlewareGroups['api'] 里,而不是全局中间件

config/cors.php 的关键配置项怎么填

config/cors.php 看似简单,但几个字段填错就等于没配。最常踩的坑是 'allowed_origins' 写成 ['*'] 却又开了 'supports_credentials' => true——这会直接被浏览器拒绝,因为 credentials 和通配符 origin 不兼容。

  • 'allowed_origins':开发环境可写 ['http://localhost:3000', 'http://127.0.0.1:8080'];生产环境禁止用 ['*'],必须列明具体域名
  • 'supports_credentials':只要前端带了 withCredentials: true(比如要传 cookie),这里就必须设为 true,同时 allowed_origins 不能是 ['*']
  • 'allowed_headers':至少包含 ['*'] 或显式列出 ['Content-Type', 'X-Requested-With', 'Authorization'];如果前端发了自定义 header(如 X-Api-Key),必须加进去
  • 'exposed_headers':一般不用动;只有前端 js 需要读取响应头(如 response.headers.get('X-RateLimit-Remaining'))时才填

API 路由没走 CORS 中间件?检查路由分组和中间件顺序

即使中间件注册了,Laravel 路由匹配顺序不对,HandleCors 也可能被跳过。典型表现:GET 请求能通,但 POST 报跨域错误——因为 POST 被其他中间件(比如 ThrottleRequests)提前拦截或终止,HandleCors 根本没执行。

  • 确保 API 路由定义在 routes/api.php,且使用了 Route::middleware('api') 分组(Laravel 默认已绑定 HandleCors 到该分组)
  • 不要手动在单个路由上加 ->middleware('cors');旧版文档有误导,新版统一走中间件组
  • 如果用了自定义中间件(比如权限校验),把它放在 HandleCors 之后;否则预检请求可能被你的中间件拒绝,导致连 OPTIONS 都不回
  • 调试技巧:在 HandleCors::handle() 里加 dd('cors hit'),看是否被执行

Laravel 10+ 使用 Sanctum 时 CORS 更容易出问题

Sanctum 自带 session 认证逻辑,而 HandleCors 必须在 session 启动前运行,否则 cookie 相关头(Set-Cookie)无法透出。常见现象:登录成功但后续请求 401,或者浏览器提示 Failed to fetch

  • 确保 FruitcakeCorsHandleCors::classapp/Http/Kernel.php$middleware 数组中排在 IlluminateSessionMiddlewareStartSession::class 之前
  • Sanctum 的 stateful 域名列表(config/sanctum.php 中的 'stateful')必须和 cors.allowed_origins 完全一致,包括协议、端口
  • 如果前端用 axios,务必设置 withCredentials: true;fetch 则要加 credentials: 'include',否则 cookie 不发,后端认不出用户

跨域不是开关一开就完事,origin、credentials、header、中间件顺序、认证方案——四个点里错一个,请求就静默失败。别信“配了 config 就行”,得逐层验证中间件是否真跑到了、响应头是否真返回了、浏览器是否真收到了。

text=ZqhQzanResources