Laravel跨域配置需正确返回CORS响应头并处理OPTIONS预检,推荐用fruitcake/laravel-cors包(Laravel 8+官方路径),关键要将HandleCors中间件置于Kernel.php的$middleware顶部;也可自定义CorsMiddleware或在Nginx/Apache层配置,须注意credentials与通配符冲突、预检被Nginx拦截等常见问题。

直接在 Laravel 中配置接口跨域,核心是让服务器对符合条件的请求返回正确的 CORS 响应头,并正确处理浏览器发起的 OPTIONS 预检请求。配置不生效,往往不是写错参数,而是中间件没挂对位置、预检被 Nginx 拦截,或 credentials 和通配符冲突。下面分几种实用方式说明:
用 fruitcake/laravel-cors 包(推荐,Laravel 8+ 官方路径)
这是目前最稳定、可维护性最强的方式,尤其适合 API 路由较多的项目。
- 安装:运行
composer require fruitcake/laravel-cors(Laravel 9+ 已内置类但需手动启用) - 发布配置:执行
php artisan vendor:publish --provider="Fruitcake\Cors\CorsServiceProvider",生成config/cors.php - 关键配置项要改对:
-
'paths' => ['api/*', 'sanctum/csrf-cookie']—— 明确哪些路由需要跨域 -
'allowed_origins' => ['http://localhost:3000', 'https://yourapp.com']—— 不能写['*']如果启用了凭证 -
'supports_credentials' => true时,必须配套设置SESSION_DOMAIN(如.yourapp.com)且前端 fetch 要加credentials: 'include'
-
- 中间件注册位置很重要:打开
app/Http/Kernel.php,把\Fruitcake\Cors\HandleCors::class加到$middleware数组**顶部**(不是$middlewareGroups['api']里),否则非 api 组路由(比如/sanctum/csrf-cookie)不会走 CORS
自定义中间件(轻量、可控、适合简单场景)
不需要额外包,适合只开放个别接口、或需动态判断 origin 的情况。
- 生成中间件:
php artisan make:middleware CorsMiddleware - 在
handle方法中添加响应头(注意区分 OPTIONS 请求):public function handle($request, \Closure $next)<br>{<br> $response = $next($request);<br><br> $origin = $request->header('Origin', '');<br> $allowedOrigins = ['http://localhost:3000', 'https://myapp.com'];<br> if (in_array($origin, $allowedOrigins)) {<br> $response->headers->add(['Access-Control-Allow-Origin' => $origin]);<br> $response->headers->add(['Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS']);<br> $response->headers->add(['Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With']);<br> $response->headers->add(['Access-Control-Allow-Credentials' => 'true']);<br> }<br><br> // 单独处理 OPTIONS 预检<br> if ($request->isMethod('OPTIONS')) {<br> return response('', 200)->headers->add(['Access-Control-Allow-Origin' => $origin]);<br> }<br><br> return $response;<br>} - 注册中间件:在
app/Http/Kernel.php的$middlewareGroups['api']或全局$middleware中加入,例如:'cors' => \App\Http\Middleware\CorsMiddleware::class
绕过 PHP 层,在 Nginx/Apache 配置(高效、适合生产环境)
如果后端逻辑简单、且你有服务器权限,直接在 Web 服务器层加头更高效,也避免 PHP 处理 OPTIONS 请求。
- Nginx 示例(加在 server 块内):
location ~ ^/api/ {<br> add_header 'Access-Control-Allow-Origin' 'https://yourapp.com';<br> add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';<br> add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With';<br> add_header 'Access-Control-Allow-Credentials' 'true';<br> add_header 'Access-Control-Max-Age' 86400;<br><br> if ($request_method = 'OPTIONS') {<br> add_header 'Access-Control-Allow-Origin' 'https://yourapp.com';<br> add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';<br> add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With';<br> add_header 'Access-Control-Allow-Credentials' 'true';<br> add_header 'Access-Control-Max-Age' 86400;<br> add_header 'Content-Length' 0;<br> add_header 'Content-Type' 'text/plain; charset=utf-8';<br> return 204;<br> }<br>} - 注意:Nginx 必须把 OPTIONS 请求透传给 PHP,否则 Laravel 根本收不到;若 Nginx 直接返回 204,就无需 Laravel 再处理预检
常见踩坑点提醒
很多问题不是配置错,而是细节被忽略:
- allowed_origins 写了 ['*'] 却开了 supports_credentials → 浏览器直接报错,必须换为具体域名
- 前端用了 credentials: 'include',但后端没设 supports_credentials => true 且没配 SESSION_DOMAIN → Cookie 不会发送,登录态丢失
-
路由没套 middleware('api') → 即使配了
$middlewareGroups['api'],普通 Route::get() 也不走 HandleCors - Nginx 拦截了 OPTIONS 请求 → 查看 Nginx error log,确认是否返回 404/500;Laravel 日志里看不到这条请求,说明根本没进 PHP
-
allowed_headers 含自定义字段(如 X-Api-Key)却没显式列出 → 不能只靠
['*'],部分浏览器不认,需写成['Content-Type', 'Authorization', 'X-Api-Key']


















