You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGINX多Laravel项目配置:静态资源路径缺失问题求助

NGINX下多Laravel项目子路径访问的静态资源修复方案

一、核心问题分析

你遇到的问题本质是Laravel无法感知请求的项目路径前缀,导致asset()生成的URL缺少/my-new-project这类前缀;同时NGINX需要正确映射静态资源路径到对应项目的public目录,并将完整请求URI传递给Laravel。

二、修正NGINX配置

假设所有Laravel项目存储在/var/www/laravel-projects/目录下,每个项目以独立文件夹命名(如my-new-project),入口为/var/www/laravel-projects/my-new-project/public/index.php。替换你的NGINX server配置为以下内容:

server {
    listen 80;
    server_name webs.example.com;

    # 捕获项目路径前缀,处理所有以 /<项目名> 开头的请求
    location ~ ^/([^/]+)/(.*)$ {
        # 指向对应项目的public目录
        root /var/www/laravel-projects/$1/public;
        index index.php index.html;

        # 优先返回存在的静态资源,不存在则转发到项目的index.php
        try_files $2 $2/ /$1/index.php?$query_string;

        # PHP-FPM处理配置(根据你的PHP版本调整sock路径)
        location ~ \.php$ {
            fastcgi_pass unix:/run/php/php8.1-fpm.sock;
            fastcgi_index index.php;
            # 指向项目public目录下的index.php
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
            # 传递完整的请求URI,包含项目前缀,确保Laravel路由解析正确
            fastcgi_param REQUEST_URI /$1/$2;
            # 传递PATH_INFO,避免Laravel路由异常
            fastcgi_param PATH_INFO $2;
            include fastcgi_params;
        }
    }

    # 根路径返回404,或可配置默认项目
    location / {
        return 404;
    }
}

关键配置说明:

  • location ~ ^/([^/]+)/(.*)$:用正则捕获第一个路径段作为项目名($1),剩余部分作为请求路径($2)。
  • try_files $2 $2/ /$1/index.php?$query_string:先尝试访问静态资源,不存在则交给Laravel入口处理。
  • fastcgi_param REQUEST_URI /$1/$2:确保Laravel拿到包含项目前缀的完整请求地址,这是路由和asset生成正确URL的基础。

三、Laravel端配置调整

要让asset()自动生成带项目前缀的URL,推荐通过中间件动态设置:

步骤1:创建中间件

在项目中创建app/Http/Middleware/SetAssetPrefix.php:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\URL;

class SetAssetPrefix
{
    public function handle($request, Closure $next)
    {
        $segments = $request->segments();
        // 提取第一个路径段作为项目前缀
        if (!empty($segments[0])) {
            $prefix = $segments[0];
            // 强制Laravel使用带前缀的根URL
            URL::forceRootUrl(url("/$prefix"));
        }

        return $next($request);
    }
}

步骤2:注册中间件

打开app/Http/Kernel.php,在web中间件组中添加该中间件:

protected $middlewareGroups = [
    'web' => [
        // 保留原有中间件,添加下面一行
        \App\Http\Middleware\SetAssetPrefix::class,
    ],
];

这样,所有asset()生成的URL都会自动带上项目前缀,比如asset('/resources/xxx')会输出webs.example.com/my-new-project/resources/xxx。

四、对比Apache的.htaccess逻辑

你的Apache配置本质是通过RewriteBase和RewriteRule固定项目前缀,将请求转发到对应项目的index.php。NGINX的配置实现了相同的逻辑:

  • 静态资源优先直接返回
  • 动态请求转发到项目入口
  • 确保框架能获取完整的请求路径(包含前缀)

五、验证步骤

  1. 重启NGINX生效配置:sudo systemctl restart nginx
  2. 访问项目入口webs.example.com/my-new-project,确认页面加载正常
  3. 查看页面源码,检查静态资源URL是否包含项目前缀
  4. 直接访问静态资源地址,确认能正常加载

内容的提问来源于stack exchange,提问作者Johnczek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 15:13:22