为什么 nginx 内部重定向没有发生

为什么 nginx 内部重定向没有发生

我很确定我错过了一个显而易见的事情但这让我发疯,我需要其他的眼球......

我得到了一个带有插件的应用程序,其源的组织方式如下:

/app/plugins/foo/www/... 对应于我的 URLhttp://example.com/plugins/foo/...

我得到以下代码片段作为 nginx 配置:

location /plugins/foo {
    alias /app/plugins/foo/www;
    try_files $uri /index.php =404;
}

location ~* ^/plugins/foo/(.*\.php)$ {
    alias /app/plugins/foo/www/$1;

    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

它适用于以下 URL:

但是当我尝试到达(前端控制器模式)时:

我必须下载 php 文件。

根据日志,try_files 似乎执行了预期的操作,但它没有将内部重定向到 php 处理程序,而是将文件作为静态服务器:

2017/01/24 13:29:36 [debug] 20803#0: *6 using configuration "/plugins/foo"
2017/01/24 13:29:36 [debug] 20803#0: *6 http cl:-1 max:1048576
2017/01/24 13:29:36 [debug] 20803#0: *6 rewrite phase: 3
2017/01/24 13:29:36 [debug] 20803#0: *6 post rewrite phase: 4
2017/01/24 13:29:36 [debug] 20803#0: *6 generic phase: 5
2017/01/24 13:29:36 [debug] 20803#0: *6 generic phase: 6
2017/01/24 13:29:36 [debug] 20803#0: *6 generic phase: 7
2017/01/24 13:29:36 [debug] 20803#0: *6 generic phase: 8
2017/01/24 13:29:36 [debug] 20803#0: *6 access phase: 9
2017/01/24 13:29:36 [debug] 20803#0: *6 access phase: 10
2017/01/24 13:29:36 [debug] 20803#0: *6 post access phase: 11
2017/01/24 13:29:36 [debug] 20803#0: *6 try files phase: 12
2017/01/24 13:29:36 [debug] 20803#0: *6 http script var: "/plugins/git/"
2017/01/24 13:29:36 [debug] 20803#0: *6 trying to use file: "/" "/app/plugins/foo/www/"
2017/01/24 13:29:36 [debug] 20803#0: *6 trying to use file: "/index.php" "/app/plugins/foo/www/index.php"
2017/01/24 13:29:36 [debug] 20803#0: *6 try file uri: "/plugins/foo/index.php"
2017/01/24 13:29:36 [debug] 20803#0: *6 content phase: 13
2017/01/24 13:29:36 [debug] 20803#0: *6 content phase: 14
2017/01/24 13:29:36 [debug] 20803#0: *6 content phase: 15
2017/01/24 13:29:36 [debug] 20803#0: *6 content phase: 16
2017/01/24 13:29:36 [debug] 20803#0: *6 content phase: 17
2017/01/24 13:29:36 [debug] 20803#0: *6 content phase: 18
2017/01/24 13:29:36 [debug] 20803#0: *6 http filename: "/app/plugins/foo/www/index.php"
2017/01/24 13:29:36 [debug] 20803#0: *6 add cleanup: 000000000153FF70
2017/01/24 13:29:36 [debug] 20803#0: *6 http static fd: 13
2017/01/24 13:29:36 [debug] 20803#0: *6 http set discard body
2017/01/24 13:29:36 [debug] 20803#0: *6 xslt filter header
2017/01/24 13:29:36 [debug] 20803#0: *6 HTTP/1.1 200 OK 

所以问题是:在这种情况下如何实现我的前端控制器模式?

编辑

location /plugins/foo {
    alias /app/plugins/foo/www;
    try_files $uri /plugins/foo/index.php?$args;
}

我被重定向到核心前端控制器而不是插件控制器:

2017/01/25 13:45:48 [debug] 14086#0: *197 using configuration "/plugins/foo"
...
2017/01/25 13:45:48 [debug] 14086#0: *197 try files phase: 12
2017/01/25 13:45:48 [debug] 14086#0: *197 http script var: "/plugins/foo/"
2017/01/25 13:45:48 [debug] 14086#0: *197 trying to use file: "/" "/app/plugins/foo/www/"
2017/01/25 13:45:48 [debug] 14086#0: *197 http script copy: "/plugins/git/index.php?"
2017/01/25 13:45:48 [debug] 14086#0: *197 http script var: "group_id=101"
2017/01/25 13:45:48 [debug] 14086#0: *197 trying to use file: "/index.php?group_id=101" "/app/plugins/foo/www/index.php?group_id=101"
====> ??? 2017/01/25 13:45:48 [debug] 14086#0: *197 internal redirect: "/index.php?group_id=101"
2017/01/25 13:45:48 [debug] 14086#0: *197 rewrite phase: 1
...

为什么重定向到/index.php?group_id=101何时/app/plugins/foo/www/index.php?group_id=101有效?

答案1

为了避免长期存在的问题alias和一起使用try_files,你可以使用if块来代替(注意注意使用限制)。另请注意,$request_filename使用 而不是 来$document_root$fastcgi_script_name获取别名路径名。

我已经测试过这个例子:

location ^~ /plugins/foo {
    alias /app/plugins/foo/www;

    if (!-e $request_filename) {
        rewrite ^ /plugins/foo/index.php last;
    }

    location ~ \.php$ {
        if (!-f $request_filename) {
            rewrite ^ /plugins/foo/index.php last;
        }
        fastcgi_pass 127.0.0.1:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
    }
}
  • 修改^~器使此location块优先于location同一级别的其他块(参见这个文件)。
  • rewrite语句会自动附加参数(参见这个文件)。
  • 嵌套location块处理别名范围内的 PHP 文件。
  • 总是include fastcgi_params; 用来fastcgi_param避免后者被包含的文件悄悄覆盖。

相关内容