我在 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
。问题解决了。