laravel子域名跨域问题核心在于options预检失败及credentials配置冲突:需确保handlecors注册于api中间件组、supports_credentials为true时allowed_origins不能为['*']而须明确域名或使用allowed_origins_patterns正则匹配,同时nginx透传options请求并配置paths包含'sanctum/csrf-cookie'。

子域名跨域读取 GET 参数本身不触发跨域限制,真正卡住的是后续的 POST/PUT 请求或带 credentials 的请求——因为浏览器在发这些请求前会先发 OPTIONS 预检,而 Laravel 默认不响应它。
为什么子域名请求能发出去却拿不到 GET 参数?
这不是 CORS 问题,而是你前端代码里没正确解析 URL。浏览器允许跨子域名发起 GET 请求(比如 https://app.example.com 调用 https://api.example.com/users?id=123),但如果你用 fetch 或 axios 发请求后没手动从 URL 中提取参数,或者后端路由没匹配上,就会“看起来像读不到”。
- 检查前端是否真的把参数拼进了 URL:比如
axios.get('https://api.example.com/users', { params: { id: 123 } })会生成/users?id=123,但若你漏了{ params: ... },参数根本不会出现 - 确认 Laravel 路由定义在
routes/api.php,且用了Route::middleware('api')分组——否则中间件(包括 CORS)不生效 - 子域名间共享 Cookie 需额外配置:前端必须设
withCredentials: true,后端config/cors.php中supports_credentials要为true,且allowed_origins不能是['*'],得写成['https://app.example.com']
子域名下 OPTIONS 预检失败的典型表现
GET 请求成功,但紧接着的 POST 报 403 Forbidden 或 net::ERR_FAILED,控制台看到一个 OPTIONS 请求返回 404 或 500——说明预检没被 Laravel 拦截处理。
- Laravel 9+ 默认已集成
fruitcake/laravel-cors,但必须确保\Fruitcake\Cors\HandleCors::class出现在$middlewareGroups['api']里,不是全局$middleware - 如果用了 Sanctum,
config/cors.php中的paths至少要包含'sanctum/csrf-cookie',否则 CSRF 预检就挂了 - 别在
routes/web.php里定义 API 路由——web 组默认不加载api中间件组,HandleCors根本不执行
config/cors.php 子域名场景关键配置项
填错任意一项,整个 CORS 就形同虚设。尤其注意 allowed_origins_patterns 是比 allowed_origins 更适合子域名的写法。
-
allowed_origins:开发期可写['https://app.example.com', 'https://admin.example.com'];生产环境禁止用['*'] -
allowed_origins_patterns:支持正则,子域名通配更安全,例如['https://*.example.com'](注意开头要有https://) -
supports_credentials:只要前端带了withCredentials: true(比如传 Cookie 或 Authorization header),这里就必须是true,否则浏览器直接拒绝响应 -
allowed_headers:如果前端发了X-Requested-With或自定义头(如X-App-Version),必须显式列出来,不能只靠['*'](某些旧版 Laravel 不完全兼容)
调试时最容易忽略的三件事
90% 的“子域名跨域失败”其实和 CORS 配置无关,而是环境或路径细节没对齐。
- 本地开发用
http://localhost:3000访问https://api.example.com?协议不同(HTTP vs HTTPS)也算跨域,allowed_origins得同时写两个协议版本 - 运行过
php artisan config:clear吗?改完config/cors.php不清缓存,Laravel 仍读旧配置 - 检查 Nginx/Apache 是否覆盖了响应头:反向代理层可能删掉了 Laravel 添加的
Access-Control-Allow-Origin,此时得在 Web 服务器配置里补上











