Laravel API跨域问题可通过五种方法解决:一、安装laravel-cors包并配置;二、路由中用withHeaders设置头;三、自定义中间件添加响应头;四、捕获OPTIONS预检请求;五、在Nginx/Apache服务器层配置CORS头。

如果您在使用 Laravel 开发 API 接口时,前端应用(如 Vue、React 或纯 HTML 页面)发起请求遭遇浏览器拦截,提示“CORS 头缺失”或“跨域请求被拒绝”,则说明当前 Laravel 应用未正确配置跨域资源共享策略。以下是解决此问题的步骤:
一、使用 laravel/sanctum 或 laravel/cors 包启用全局 CORS 支持
该方法通过官方推荐的 fruitcake/laravel-cors 包实现中间件级跨域控制,适用于 Laravel 8 及以上版本(Laravel 9+ 已默认集成该功能逻辑,但仍需手动配置)。安装后可对所有路由或指定路由组统一启用跨域响应头。
1、执行 Composer 命令安装扩展包:composer require fruitcake/laravel-cors。
2、发布配置文件:php artisan vendor:publish --provider="Fruitcake\Cors\CorsServiceProvider"。
3、编辑 config/cors.php 文件,将 'paths' 设置为 ['api/*', 'sanctum/csrf-cookie'],并将 'allowed_origins' 设为 ['*'] 或具体域名列表(如 ['https://example.com', 'http://localhost:3000'])。
4、确保 App\Http\Kernel.php 中的 $middlewareGroups['api'] 数组已包含 \Fruitcake\Cors\HandleCors::class。
二、在路由定义中直接调用 withHeaders 方法设置响应头
该方法适用于仅需对个别接口开放跨域权限的场景,不依赖中间件,通过链式调用直接注入响应头,轻量且精准控制。
1、打开 routes/api.php 文件。
2、在目标路由定义后添加 ->withHeaders(['Access-Control-Allow-Origin' => '*']),例如:Route::get('/data', [DataController::class, 'index'])->withHeaders(['Access-Control-Allow-Origin' => 'https://myapp.com']);。
3、若需支持凭证(如 Cookie),还需追加 'Access-Control-Allow-Credentials' => 'true',并确保 allowed_origins 不为通配符 *。
三、自定义中间件强制添加 CORS 响应头
该方法绕过第三方包,完全由开发者控制响应头内容,适合需要动态判断来源域名、或与现有鉴权逻辑深度耦合的项目。
1、生成中间件:php artisan make:middleware AddCorsHeaders。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
2、编辑 app/Http/Middleware/AddCorsHeaders.php,在 handle() 方法中添加:$response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin') ?: '*');。
3、添加其他必要头字段:$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); 和 $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');。
4、在 app/Http/Kernel.php 的 $middlewareGroups['api'] 中注册该中间件。
四、覆盖默认的 OPTIONS 预检请求处理逻辑
当浏览器发送预检请求(OPTIONS)时,Laravel 默认可能返回 405 错误。该方法显式捕获并响应 OPTIONS 请求,避免预检失败导致后续请求被阻断。
1、在 routes/api.php 顶部添加通配路由:Route::options('{any}', function () { return response('', 200)->header('Access-Control-Allow-Origin', '*')->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With'); })->where('any', '.*');。
2、确保该路由位于所有其他路由定义之前,以优先匹配 OPTIONS 请求。
3、若使用 Sanctum 或 Passport 认证,需额外添加 Access-Control-Allow-Credentials 并限制 Access-Control-Allow-Origin 为具体域名。
五、修改 Apache 或 Nginx 服务器配置直接注入 CORS 头
该方法在 Web 服务器层处理跨域,绕过 PHP 应用逻辑,性能更高,适用于部署环境已明确且无法修改 Laravel 代码的情况。
1、对于 Nginx,在站点配置的 location 块内添加:add_header 'Access-Control-Allow-Origin' '*' always;。
2、补充必要头信息:add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always; 和 add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;。
3、为兼容预检请求,添加:if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; }。










