在 nginx 中使用 fastcgi 重写 url

在 nginx 中使用 fastcgi 重写 url

我在 nginx 中有一个有效的 php fastcgi 配置。现在我有几个请求需要处理,例如,听起来很/X.php简单 ,所以我写了以下内容进行测试:/X/Y.php/Y

rewrite ^/X.php$ /api/v1/stat last;

它被 php 应用程序的 404 处理程序捕获。以下是启用了 rewrite_log 的 nginx 错误日志

[notice] 15289#0: *759 "^/X.php$" matches "/X.php", client: 10.0.0.12, server: example.com, request: "GET /X.php HTTP/1.1", host: "example.com"
[notice] 15289#0: *759 rewritten data: "/api/v1/stat", args: "", client: 10.0.0.12, server: example.com, request: "GET /X.php HTTP/1.1", host: "example.com"
[notice] 15289#0: *759 "^/X.php$" does not match "/index.php", client: 10.0.0.12, server: example.com, request: "GET /X.php HTTP/1.1", host: "example.com"

如果我直接访问 /api/v1/stat,它会起作用:

[notice] 15125#0: *708 "^/X.php$" does not match "/api/v1/stat", client: 223.104.3.248, server: example.com, request: "GET /api/v1/stat HTTP/1.1", host: "example.com"
[notice] 15125#0: *708 "^/X.php$" does not match "/index.php", client: 223.104.3.248, server: example.com, request: "GET /api/v1/stat HTTP/1.1", host: "example.com"

以下是我的相关 nginx 配置:

rewrite ^/X.php$    /api/v1/stat last;

location / {
    try_files $uri $uri/ /index.php;
}

location ~ .*\.php$ {
    try_files $uri =404;
    include        fastcgi_params;
    fastcgi_pass   php;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
}

upstream php {
    server unix:/var/run/php-fpm.sock;
}

请帮我想出一个解决办法。谢谢。

笔记

一些背景知识也许能帮助你理解我的问题。

显然,下面的方法应该可行,而且确实可行:

rewrite ^/X.php$ /api/v1/stat permanent;

但是,我正在处理某种不理解 301 重定向的硬件,因此我尝试使用内部重定向而不显示重定向。

更新 1

我想到的解决办法只是一半。我成功地/X.php重定向了/api/v1/stat。但是,重定向后无法传递任何参数。我想rewrite传递参数$args,但不起作用。我现在不知所措。

更新2

问题解决了。尽管我仍不确定为什么$args没有传递下去。

答案1

重写 ^/X.php$ /api/v1/stat 最后;将您发送到“位置/”

例如,您可以使用另一个位置来匹配此内部重定向:“/api/v1/stat”

在此位置您可以将请求传递给 fcgi-backend(或者在此位置对其进行另外修改)。

答案2

打开 nginx 调试模式并比较工作请求与失败请求之间的日志给了我一个线索:失败请求的 nginx REQUEST_URI变量/X.php即使在重写之后也没有更新。参见nginx 文档中的变量

所以我需要REQUEST_URI在重写后进行更新。这个帖子来自 SO 的帮助可以解决这个问题。

以下是对我有用的方法:

set $request_url $request_uri;
if ($request_uri ~ ^/X.php(.*)$ ) {
    set $request_url   /api/v1/x$1;
    rewrite ^/X.php    /api/v1/x  last;
}

location ~ .*\.php$ {
    try_files $uri =404;
    include        fastcgi_params;
    fastcgi_pass   php;
    fastcgi_index  index.php;

    fastcgi_param  REQUEST_URI        $request_url;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
}

更新

最后,这也适用于重写中的查询字符串。我在if子句中添加了匹配的查询字符串,并将匹配的查询字符串附加到request_url。问题解决了。

相关内容