Laravel多域名配置需同步修改APP_URL、SESSION_DOMAIN、路由domain()分组、Web服务器配置及清除所有缓存,否则会导致URL生成错误、Cookie失效、资产404、路由不匹配等问题。

直接改 APP_URL 不够,Laravel 多处逻辑依赖域名,只改环境变量会导致路由生成错误、Cookie 域名失效、资产链接错乱等问题。
APP_URL 不是唯一要改的地方
很多人以为把 .env 里的 APP_URL 换成新域名就完事了,结果访问页面时 CSS 加载 404、登录后跳转回旧域名、邮件里链接还是老地址——这是因为 Laravel 在多个环节硬编码或缓存了域名信息。
-
url()、route()、asset()等辅助函数默认以APP_URL为根,但若 Web 服务器未透传 Host 头(比如 Apache 的UseCanonicalName On),request()->getHost()可能返回 IP 或默认虚拟主机名,导致 URL 生成与实际请求不一致 -
SESSION_DOMAIN必须显式设置(如.example.com),否则 Cookie 不会跨子域共享;漏掉开头的点号(.example.comvsexample.com)会导致子域名间无法携带会话 - 邮件模板、通知类中硬写的链接(如
https://old.com/reset)不会自动替换,需全局搜索old.com并人工确认上下文
路由 domain() 分组必须同步更新
如果你用 Route::domain('old.com') 或 Route::domain('{sub}.old.com') 定义了域名约束,这些字符串必须批量替换成新域名。否则新域名请求根本匹配不到路由,直接 404。
- 检查
routes/web.php、routes/api.php,以及app/Providers/RouteServiceProvider.php中mapWebRoutes()内部是否手动调用了Route::domain() - 注意通配符写法:
Route::domain('{sub}.old.com')要改成Route::domain('{sub}.new.com'),不能只改old.com字符串而漏掉{sub}.前缀部分 - 如果用了第三方包(如
gecche/laravel-multidomain),它可能从.env读取MULTIDOMAIN_MAIN_DOMAIN或类似配置项,需一并核对
Web 服务器配置常被忽略
本地开发(Wamp/Laragon)或线上 Nginx/Apache 的虚拟主机配置,必须指向新域名,否则请求压根进不了 Laravel。
- Wamp:修改
httpd-vhosts.conf里的ServerName和ServerAlias,并同步更新C:\Windows\System32\drivers\etc\hosts中的映射行(如新增127.0.0.1 new.test) - Laragon:右键托盘 → Quick App → 重新绑定新域名,或手动编辑
laragon/etc/apache2/sites-enabled/new.test.conf - Nginx:确认
server_name包含新域名,且没有遗漏泛解析(如server_name *.new.com new.com;) - Apache:检查
VirtualHost的ServerName和DocumentRoot是否仍指向旧项目路径(尤其是迁移后项目目录变更时)
缓存和预编译文件要清干净
改完配置不清理缓存,大概率看到的是旧行为——因为 Laravel 会把路由、配置、视图甚至 URL 生成逻辑固化到缓存文件里。
- 执行
php artisan config:clear、php artisan route:clear、php artisan view:clear - 如果启用了 OPCache 或 APCu,重启 PHP-FPM 或 Web 服务进程(
sudo systemctl restart php8.2-fpm或httpd) - 特别注意:若运行过
php artisan route:cache,旧路由规则会完全屏蔽新domain()配置,必须先route:clear再重缓存 - 前端构建产物(如 Vite / Mix 输出的
mix-manifest.json)若内嵌了旧域名,需重新npm run build
最易被忽略的是 Web 服务器是否真正把原始 Host 头传给了 PHP —— 尤其在反向代理(Nginx → Apache)、Docker 或某些云 WAF 后面时,request()->getHost() 可能返回代理 IP 或默认值,导致 Route::domain() 失效。上线前务必用 dd(request()->getHost()) 实测请求头真实值。


















