Laravel 13支持通过allowed_origins_patterns正则匹配子域名跨域,需清空allowed_origins、启用supports_credentials、确保HandleCors在中间件首位,并配置Nginx透传OPTIONS请求。

Laravel 13(截至2026年11月尚未正式发布,当前最新稳定版为 Laravel 11,但假设你指代的是支持 allowed_origins_patterns 的现代 Laravel 版本,即 ≥9.2)支持用正则表达式匹配跨域来源,这对前端部署在多个子域名(如 app.example.com、admin.example.com、staging.app.example.com)的场景非常实用。
关键前提是:*不能用 `allowed_origins => [''],也不能硬编码每个子域名**——而应启用并正确配置allowed_origins_patterns`。
✅ 正确配置子域名正则放行(以 .example.com 及其所有子域为例)
打开 config/cors.php,找到并修改以下两项:
'allowed_origins_patterns' => [
'^https?://([a-z0-9.-]+\.)?example\.com(:[0-9]+)?$',
],
'allowed_origins' => [],
'supports_credentials' => true,⚠️ 注意:
allowed_origins必须为空数组(或注释掉/删掉),否则allowed_origins_patterns会被忽略。Laravel 仅在allowed_origins为空时才启用正则匹配。立即学习“前端免费学习笔记(深入)”;
正则说明:
-
^https?://:匹配http://或https:// -
([a-z0-9.-]+\.)?:可选的子域名部分(如app.、admin.、staging.dev.),支持多级(.要转义) -
example\.com:精确匹配主域名(.同样需转义) -
(:[0-9]+)?:可选端口(开发时本地调试如:3000也能匹配) -
$:确保结尾,防误匹配(如example.com.hacker.site)
✅ 示例匹配:
-
https://app.example.com✔ -
http://admin.example.com:8080✔ -
https://staging.api.example.com✔ -
https://example.com✔(无子域也匹配) -
https://evil.com.example.com✘(不满足.example.com结尾)
✅ 中间件必须启用且位置正确
确保 app/Http/Kernel.php 中:
-
HandleCors已加入 全局中间件数组$middleware顶部(不是api组内):protected $middleware = [ FruitcakeCorsHandleCors::class, // 必须在最前面 AppHttpMiddlewareTrustProxies::class, // ... 其他中间件 ]; -
若你用的是 Sanctum + Session(如
sanctum/csrf-cookie),还需确认:-
SESSION_DOMAIN=.example.com(注意开头的点,使 Cookie 被所有子域共享) -
supports_credentials => true已开启(与正则配套)
-
✅ Nginx 需透传 OPTIONS 请求(常被忽略)
即使 Laravel 配置正确,若 Nginx 拦截了预检请求(OPTIONS),CORS 依然失败。在站点配置中添加:
location / {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Max-Age "86400" always;
return 204;
}
}? 实际上,Nginx 这段只是“兜底”——真正生效的 CORS 头仍由 Laravel 的
HandleCors中间件生成并返回。但预检请求必须到达 PHP 层,所以if (OPTIONS) { return 204; }是安全且推荐的做法。
❌ 常见错误排查
-
A wildcard '*' cannot be used错误 → 检查是否同时设置了'allowed_origins' => ['*']和'supports_credentials' => true,二者互斥,必须清空allowed_origins改用allowed_origins_patterns - 子域名不生效 → 打开浏览器开发者工具 → Network → 看预检(OPTIONS)响应头里是否有
Access-Control-Allow-Origin,没有则中间件未运行;有但值不对,则正则写错或未命中 - Cookie 不随请求发送 → 前端
fetch必须带credentials: 'include',后端supports_credentials => true,且SESSION_DOMAIN设置正确(.example.com)
不复杂但容易忽略。


















