Laravel 11 默认内置 HandleCors 中间件,无需安装 fruitcake/laravel-cors;需手动发布 config/cors.php、将 \Illuminate\Http\Middleware\HandleCors::class 置于 $middleware 数组顶部,并在 Nginx 中正确处理 OPTIONS 预检请求。

Laravel 11 默认已集成 CORS 支持,不再需要额外安装 fruitcake/laravel-cors,但配置仍需手动完成,且极易因路径、顺序或细节疏漏导致 “No 'Access-Control-Allow-Origin' header” 错误。问题本质不是没加头,而是头根本没发出去——常见于中间件未生效、预检请求被拦截,或 Nginx 层直接截断。
确认并修正中间件注册位置
Laravel 11 使用内置 Illuminate\Http\Middleware\HandleCors,但它只在正确位置注册才起作用:
- 打开
app/Http/Kernel.php,找到$middleware数组(不是$middlewareGroups['api']) - 确保
\Illuminate\Http\Middleware\HandleCors::class位于该数组**最顶部**(早于其他中间件,如TrustProxies或认证中间件) - 如果用的是 Sanctum 或 Jetstream,检查是否误将路由定义在
web中间件组下——CORS 中间件默认只对api/*路径生效,web组不自动启用
检查并精调 config/cors.php 配置
运行 php artisan vendor:publish --tag=cors 生成配置文件后,重点修改以下几项:
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
-
'paths' => ['api/*', 'sanctum/csrf-cookie']:确保你的 API 路由前缀匹配(例如Route::get('/user', ...)在routes/api.php中,路径就是api/user) -
'allowed_origins' => ['http://localhost:5173', 'https://your-frontend.com']:开发用具体地址,禁用['*'];若设'supports_credentials' => true(如带 Cookie 或 Token),allowed_origins必须为明确域名,不可通配 -
'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With']:前端实际发送的自定义 Header(如X-Api-Key)必须显式列出,['*']在部分浏览器中无效 - 改完记得清配置缓存:
php artisan config:clear(生产环境尤其关键)
排查 Nginx 是否劫持了 OPTIONS 请求
浏览器发起跨域 POST/PUT 等非简单请求时,会先发 OPTIONS 预检。若 Nginx 没处理它,Laravel 根本收不到请求,自然不会加头:
- 在 Nginx 的
location ~ ^/api/块内添加:
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "http://localhost:5173";
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 "86400";
return 204;
}
# 正常响应头(放在 location 内,非 server 级)
add_header Access-Control-Allow-Origin "http://localhost:5173";
add_header Access-Control-Allow-Credentials "true";
- 注意:
add_header不继承,必须写在匹配请求路径的location块里,不能只放在server块顶层 - 重启 Nginx:
sudo systemctl restart nginx
快速验证与兜底方案
若仍不确定是哪一环出问题,可临时加个最小化测试:
- 在
routes/api.php中加一条裸路由:Route::get('/test-cors', fn() => response()->json(['ok' => true]))->withHeaders(['Access-Control-Allow-Origin' => 'http://localhost:5173']); - 访问该 URL,看响应头是否含
Access-Control-Allow-Origin。若有,说明 Laravel 层正常,问题在通用配置或 Nginx;若无,说明中间件完全未触发 - 生产环境上线前,务必把
allowed_origins从['*']改为精确域名列表,避免安全风险

















