最推荐使用fruitcake/laravel-cors包(Laravel 9.2+已内置),通过发布config/cors.php配置allowed_origins、methods等,并将HandleCors中间件置于Kernel.php的$middleware顶部,以统一、安全地处理跨域及OPTIONS预检请求。

直接在 Laravel 接口上配置 CORS,核心是让响应头包含 Access-Control-Allow-Origin 等必要字段,并正确处理浏览器发起的 OPTIONS 预检请求。最稳妥、推荐的方式是使用官方生态支持的 fruitcake/laravel-cors 包(Laravel 9.2+ 已内置逻辑),而不是手动拼 header 或临时加中间件。
用 fruitcake/laravel-cors 统一管理(推荐)
这是目前 Laravel 社区最主流、最可靠的方案,自动处理预检、凭证、路径匹配等细节:
- 安装(Laravel 8 及以下需执行;Laravel 9.2+ 可跳过安装,但建议仍运行发布命令):
composer require fruitcake/laravel-cors - 发布配置文件:
php artisan vendor:publish --provider="Fruitcake\Cors\CorsServiceProvider"
生成config/cors.php - 编辑
config/cors.php,关键项示例:'paths' => ['api/*', 'sanctum/csrf-cookie'],'allowed_origins' => ['https://your-frontend.com', 'http://localhost:3000'],'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],'allowed_headers' => ['*'],'supports_credentials' => true,
⚠️ 注意:supports_credentials => true时,allowed_origins不能写['*'],必须明确列出域名 - 确保中间件注册位置正确:
打开app/Http/Kernel.php,把\Fruitcake\Cors\HandleCors::class(Laravel 9.2+ 用\Illuminate\Http\Middleware\HandleCors::class)加到$middleware数组**最顶部**(紧接TrustProxies后),而非只放在$middlewareGroups['api']里——否则非 api 组路由(如/sanctum/csrf-cookie)会失效
仅对个别接口快速放开(调试用)
适合开发阶段临时验证,不建议用于生产:
- 在
routes/api.php中直接链式设置头:Route::get('/test', [TestController::class, 'index'])->withHeaders(['Access-Control-Allow-Origin' => 'http://localhost:3000']); - 若需带 Cookie,额外加:
->withHeaders(['Access-Control-Allow-Origin' => 'http://localhost:3000','Access-Control-Allow-Credentials' => 'true']);
同时前端 fetch 必须设credentials: 'include'
自定义中间件(可控但需自行兜底)
适合有特殊鉴权逻辑或需动态判断 origin 的场景:
- 运行:
php artisan make:middleware AddCorsHeaders - 在
handle()方法中添加响应头,并显式拦截 OPTIONS 请求:if ($request->isMethod('OPTIONS')) {return response('', 200)->header('Access-Control-Allow-Origin', $origin)->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')->header('Access-Control-Allow-Headers', 'Content-Type, Authorization');}return $next($request)->header('Access-Control-Allow-Origin', $origin)->header('Access-Control-Allow-Credentials', 'true'); - 注册该中间件到
$middleware或按需绑定到路由
别漏掉服务器层(Nginx/Apache)
如果用了反向代理,且 PHP 层未生效,可能是 Nginx 拦截了 OPTIONS 请求:
- Nginx 示例(加在 server 块内):
location / {if ($request_method = 'OPTIONS') {add_header Access-Control-Allow-Origin "http://localhost:3000";add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";add_header Access-Control-Allow-Headers "Content-Type, Authorization";add_header Access-Control-Allow-Credentials "true";add_header Access-Control-Max-Age 3600;return 204;}} - 确保 Nginx 不过滤
OPTIONS,也不覆盖 PHP 设置的 header


















