【问题标题】:nginx configure /folder run from a different path than the /nginx 配置 / 文件夹从与 / 不同的路径运行
【发布时间】:2020-06-03 17:06:21
【问题描述】:

我在从与主网站不同的路径运行 /folder 时遇到问题。

该部分的我的 nginx.conf 如下所示:

        location ~ \.php$ {
            try_files               $uri = 404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param       SCRIPT_FILENAME $request_filename;
            fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
            fastcgi_index           index.php;
           include                 fastcgi_params;
            include                 fastcgi.conf;
    }


location ~ /folder {
        alias /srv/http/folder;
    try_files $uri $uri/ @folder;

    location ~ \.php$ {
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
                include        fastcgi.conf;
        }
}

location @folder {
    rewrite /folder/(.*)$ /folder/index.php?/$1 last;
}

在 error.log 中我可以看到以下内容:

2020/06/03 09:05:26 [error] 25966#25966: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.21.2.46, server: example.com, request: "GET /folder/xxx_v6.15.11/Resources/images/redcaplogo.gif HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "example.com"

有什么建议可以解决这个问题吗?

【问题讨论】:

    标签: nginx subdirectory


    【解决方案1】:

    正则表达式位置从第一个到最后一个匹配,第一个找到的匹配由 nginx 处理。当您收到/folder/script.php 的请求时,它由第一个位置块处理。尝试交换这两个位置。另外,为什么不在第二个位置块中包含 fastcgi_params

    更新

    我做了一些调试,让我们看看你的代码(假设位置块已经交换):

    location ~ /folder {
        alias /srv/http/folder;
        try_files $uri $uri/ @folder;
    
        location ~ \.php$ {
            fastcgi_param  SCRIPT_FILENAME $request_filename;
            fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
            include        fastcgi_params;
            include        fastcgi.conf;
        }
    }
    
    location ~ \.php$ {
        try_files               $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param           SCRIPT_FILENAME $request_filename;
        fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index           index.php;
        include                 fastcgi_params;
        include                 fastcgi.conf;
    }
    
    location @folder {
        rewrite /folder/(.*)$ /folder/index.php?/$1 last;
    }
    

    如果我们收到请求/folder/some/path(并且folder 内没有some/path 文件或目录),则在嵌套位置内部的nginx 变量将具有以下值:

    • $request_filename:空字符串(folder 目录内没有真正的文件或文件夹 /some/path);
    • $uri:/folder/check.php;
    • $document_root: /srv/http/folder.

    如果我们收到一个请求/folder/some/path/script.php(并且有一个具有此名称的真实 PHP 脚本),则在嵌套位置内部 nginx 变量将具有以下值:

    • $request_filename:/srv/http/folder/some/path/script.php;
    • $uri:/folder/some/path/check.php;
    • $document_root: /srv/http/folder.

    此外,当您从文件夹中收到静态资源请求时,例如 /folder/some/path/static.csstry_files $uri ... 指令将在 /srv/http/folder 目录中搜索 folder/some/path/static.css 文件,从而检查 @ 是否存在987654346@文件。

    folder 目录中获取文件子路径的一种可能解决方案:

    location ~ ^/folder(?<subpath>.*) {
        alias /srv/http/folder;
        try_files $subpath $subpath/ @folder;
    
        location ~ \.php$ {
            fastcgi_param  SCRIPT_FILENAME $document_root$subpath;
            fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
            include        fastcgi_params;
            include        fastcgi.conf;
        }
    }
    
    location ~ \.php$ {
        try_files               $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param           SCRIPT_FILENAME $request_filename;
        fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index           index.php;
        include                 fastcgi_params;
        include                 fastcgi.conf;
    }
    
    location @folder {
        rewrite ^/folder/(.*)$ /folder/index.php?/$1 last;
    }
    

    如果您的真实 folder 目录名称与您的 /folder URI 前缀相同,这可以简化:

    location ~ ^/folder {
        root /srv/http;
        try_files $uri $uri/ @folder;
    
        location ~ \.php$ {
            fastcgi_param  SCRIPT_FILENAME $document_root$uri;
            fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
            include        fastcgi_params;
            include        fastcgi.conf;
        }
    }
    
    ...
    

    作为 nginx 文档states:

    当位置与指令值的最后一部分匹配时:

    location /images/ {
      alias /data/w3/images/;
    }
    

    最好使用 root 指令:

    location /images/ {
      root /data/w3;
    }
    

    【讨论】:

    • 我已经切换了位置顺序并将factsgi_param添加到位置〜/文件夹但错误是一样的。
    • @zozo6015 一个非常有趣的!找到问题的原因,查看更新的答案。
    • 错误消失了,但是css、js、图片等静态对象还没有加载好。
    • @zozo6015 更新了答案,请检查。
    • 我不能将位置用于静态对象,因为我有多个 /folder 类型的目标位置,每个位置都有不同的静态对象路径。如果我把它放在位置 ~ /folder 内,nginx 会抱怨 nginx: [emerg] location "/images/" is outside location "/folder"
    猜你喜欢
    • 1970-01-01
    • 2020-07-09
    • 2018-11-07
    • 1970-01-01
    • 2017-06-29
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多