Laravel 12 部署到子路径时如何处理路由和资源前缀?
结论
APP_URL 不会自动为 Laravel 路由添加 /test1 前缀,也无法单独解决应用挂载在子路径下的问题。它主要用于生成 URL 时提供应用的基础地址。收到请求后,Laravel 仍会根据 Web 服务器传入的请求路径匹配路由。
从你提供的 route:list 可以看出,两类路由的处理方式不同:添加前缀后,应用路由变成了 test1/login、test1/dashboard;Boost、Flux、Livewire 和 storage 等路由仍有未加前缀的项。只有放在应用路由前缀组中的路由会受影响。
优先检查 Web 服务器传给 Laravel 的路径
访问 /test1 时,Laravel 应收到应用内路径 /;访问 /test1/login 时,应收到 /login。如果 Laravel 收到的仍是 /test1 或 /test1/login,就会按这个路径查找路由。即使 APP_URL 已正确设置,也可能因此出现 404。
先检查 Apache 重写后的请求路径、SCRIPT_NAME 等服务器变量,再确认最终处理请求的是哪个 index.php。.htaccess 将请求映射到磁盘上的 public 目录,并不意味着 Laravel 知道应用挂载在 /test1 下。具体映射方式取决于 Apache 配置和重写规则,仅凭给出的规则无法确认 Laravel 实际收到的路径。
如果可以配置虚拟主机或 Apache Alias,可以将 /test1 映射到应用的 public 目录,并配置好子路径挂载。如果只能修改公开目录中的 .htaccess,则需确保请求在进入 Laravel 前去掉 /test1 挂载前缀。还要确认 public 之外的项目文件无法通过 HTTP 访问。
应用自身的路由前缀
如果请求到达 Laravel 时仍带有 /test1,可以把应用自己定义的路由放进前缀组,例如:
use Illuminate\Support\Facades\Route;
Route::prefix('test1')->group(function () {
Route::get('/', function () {
return view('welcome');
});
// 将需要带 /test1 的应用路由放在这里
});
这只会处理分组内的路由。Fortify、Livewire、Boost、Flux 等扩展包注册的路由不会自动加入这个分组。请分别检查相关扩展包是否支持配置路由前缀;如果不支持,就不能假设统一设置能改写这些路由。不要在未确认影响的情况下修改框架或扩展包路由来修复 404。
静态资源路径
登录页请求的 /build/assets/app-DGShNaBW.css 是从站点根目录开始的路径,不包含 /test1。可以检查 Laravel Vite 的资源基础路径配置。Laravel 项目通常通过 ASSET_URL 设置资源 URL 前缀,例如:
APP_URL=http://localhost/test1
ASSET_URL=http://localhost/test1
修改配置后,如果应用启用了配置缓存,需要刷新缓存。还要确认 public/build 中的构建产物可以通过 /test1/build/... 正常访问。ASSET_URL 只处理资源 URL,不能代替路由前缀或 Web 服务器的子路径映射。
建议的排查顺序
- 检查访问
/test1/login时 Laravel 实际收到的请求路径,确认挂载前缀是否在路由匹配前被处理。 - 确认
/test1、/test1/login和/test1/build/assets/...分别由正确的应用入口或静态文件处理。 - 确有需要时再为应用路由加前缀,并分别核对 Fortify、Livewire、Boost、Flux 等扩展包的路由配置。
- 配置资源 URL 前缀后,清理适用的配置缓存,并验证浏览器请求的 CSS、JS URL。
route:list 没有读取 APP_URL,因为 APP_URL 不是全局路由前缀开关。如果服务器不能正确处理子路径挂载,且你无法调整入口请求路径,仅设置 APP_URL 和应用路由分组,无法可靠地让所有框架路由、扩展包路由和资源都带上前缀。
备注:内容仅供参考。
