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

Nginx使用变量定义root后所有URL跳转首页的问题咨询

问题成因

  1. Nginx 匹配优先级规则问题:正则匹配的优先级高于普通前缀匹配。你配置的location ~ \.(php|phar)(/.*)?$属于正则匹配,优先级比普通前缀匹配的location /更高,所有PHP请求会直接命中这个PHP处理块,完全不会进入location /的逻辑,因此你在location /中设置的root $base_root/frontend/web对PHP请求完全不生效。
  2. 根路径继承错误:PHP处理块默认继承server层级的root配置,你server层的root是$base_root = /var/www/html,当try_files把请求重写到/index.php后,PHP处理块拼接出的实际文件路径是/var/www/html/index.php,如果该路径下的文件就是你的前端首页,自然所有请求都会返回首页内容,无法触发路由解析。

修复方案

你要实现前后端分离的路径配置,只需要调整location匹配优先级,将PHP处理块嵌套到对应业务的location下即可,示例配置如下(假设后端接口统一用/api前缀,对应代码存放在/var/www/html/backend/web,你可以根据自己的实际路径调整):

server {
    set $base_root /var/www/html;
    root $base_root;
    index index.php index.html;

    # 后端接口配置
    location ^~ /api/ {
        root $base_root/backend/web;
        try_files $uri $uri/ /api/index.php$is_args$args;
        
        # 嵌套PHP处理块,继承当前location的root
        location ~ \.(php|phar)(/.*)?$ {
            fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
            fastcgi_intercept_errors on;
            fastcgi_index  index.php;

            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
            fastcgi_param  REQUEST_SCHEME     $scheme;
            fastcgi_param  HTTPS              $https if_not_empty;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;

            fastcgi_param  REDIRECT_STATUS    200;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO $fastcgi_path_info;
            fastcgi_pass   php-fpm;
        }
    }

    # 前端站点配置
    location ^~ / {
        root $base_root/frontend/web;
        try_files $uri $uri/ /index.php$is_args$args;
        
        # 嵌套PHP处理块,继承当前location的root
        location ~ \.(php|phar)(/.*)?$ {
            fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
            fastcgi_intercept_errors on;
            fastcgi_index  index.php;

            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
            fastcgi_param  REQUEST_SCHEME     $scheme;
            fastcgi_param  HTTPS              $https if_not_empty;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;

            fastcgi_param  REDIRECT_STATUS    200;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO $fastcgi_path_info;
            fastcgi_pass   php-fpm;
        }
    }
}

如果觉得重复写PHP配置太冗余,可以把公共的PHP配置抽取为独立的配置文件,比如存到/etc/nginx/snippets/php-fpm.conf,然后在对应位置用include snippets/php-fpm.conf;引入即可。

核心修改点说明

  • 用^~修饰符提升location /和location /api/的匹配优先级,匹配到对应前缀后不会再走全局的正则PHP匹配
  • 把PHP处理块嵌套到对应业务的location内部,自动继承当前location的root配置,保证PHP文件查找路径正确
  • 前后端路径分开配置,互不干扰,不需要额外加rewrite规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:09:03