nginx try_files处理两次,如果设置了错误回退,则会失败

前端之家收集整理的这篇文章主要介绍了nginx try_files处理两次,如果设置了错误回退,则会失败前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我有一个位置块设置来捕获所有文件请求并将它们发送到PHP-FPM:

location  / {
    try_files  $uri /routing.PHP?$args;
    fastcgi_pass   unix:/opt/local/var/run/PHP54/PHP-fpm-www.sock;
    include       /documents/projects/intahwebz/intahwebz/conf/fastcgi.conf;
}

这可以正确地将请求传递给PHP-FPM到请求的确切的现有PHP文件或者将routing.PHP设置为要运行的脚本.

我试图添加一个错误页面,这样如果路由文件删除或者不可用,将显示错误页面而不是Nginx的默认错误页面

location  / {
    try_files $uri /routing.PHP?$args /50x_static.html;
    fastcgi_pass   unix:/opt/local/var/run/PHP54/PHP-fpm-www.sock;
    include       /documents/projects/intahwebz/intahwebz/conf/fastcgi.conf;
}

这会停止提供routing.PHP文件,而是显示50x_static.html页面.对现有PHP文件的请求仍然有效,即转到URL /dynamic.PHP

我意识到try_files命令中的最后一个参数有点神奇:

In the event that no file is found,an internal redirect to the last
parameter is invoked. Do note that only the last parameter causes an
internal redirect,former ones just sets the internal URI pointer. The
last parameter is the fallback URI and must exist,or else an
internal error will be raised.

在调查error_page破坏配置的原因时,我意识到对于有效的配置(没有静态错误页面),在尝试获取根URL时,Nginx似乎确实根据Nginx重写日志匹配请求两次“/ “:

"^/proxy/(\d+)/(\w+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/",client: 127.0.0.1,server: basereality.com,request: "GET / HTTP/1.1",host: "basereality.test"
"^/proxy/(\d+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/",host: "basereality.test"
"^/staticImage/(\w+)/(.+)\.([^\.]*)$" does not match "/",host: "basereality.test"
"^/proxy/(\d+)/(\w+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/routing.PHP",host: "basereality.test"
"^/proxy/(\d+)/(.+)\.(gif|png|jpg|jpeg|GIF|PNG|JPG|JPEG)$" does not match "/routing.PHP",host: "basereality.test"
"^/staticImage/(\w+)/(.+)\.([^\.]*)$" does not match "/routing.PHP",host: "basereality.test"

即,请求以/作为/,try_files无法提供文件,因此从/向/routing.PHP重写请求,然后重新处理请求.

为什么尝试文件在第一次传递时不提供routing.PHP文件?它存在且可访问,否则将不会在第二轮提供.

编辑

删除了不相关的配置.

最佳答案
您引用的文档明确说“调用了最后一个参数的内部重定向”.内部重定向的处理方式与来自客户端的初始请求的处理方式相同 – 这包括处理服务器级别的重写语句,您可以在日志中看到.但是,如果除最后一个之外的任何其他try_files参数与现有文件匹配,则使用try_files语句所在的位置配置处理请求,并且不会有第二个匹配.

至于你的规则,你是否尝试在try_files中省略$args?

location  / {
    try_files $uri /routing.PHP /50x_static.html;
    fastcgi_pass   unix:/opt/local/var/run/PHP54/PHP-fpm-www.sock;
    include       /documents/projects/intahwebz/intahwebz/conf/fastcgi.conf;
}

请注意,$uri也不包含$args;查询参数仍将通过QUERY_STRING参数传递给FastCGI后端,该参数可能在fastcgi.conf中设置:

fastcgi_param QUERY_STRING    $query_string;

如果$uri和/routing.PHP都不作为文件存在,请求将被重定向到/50x_static.html并根据您的配置中的location = /50x_static.html部分进行处理(但是重写尝试的第二次迭代仍然会执行,因为您的重写规则放在服务器级别).

您的配置的一个非常可疑的细节是您通过PHP传递所有文件而不管文件扩展名 – 这是非常不寻常的,并且可能由于PHP代码在不期望的文件中执行而导致安全问题.

猜你在找的Nginx相关文章