Nginx If语句在位置之前执行?

Nginx If语句在位置之前执行?,nginx,Nginx,我不明白为什么nginx在location语句之前执行If语句。 更准确地说,为什么nginx不执行return语句,然后停止处理 即使$http\u x\u forwarded\u host不是因为if语句位于location语句下面,我也希望如果我打开/xyz,会得到一个带有“hello world”的200。但是nginx只是忽略了location语句,并遇到了if子句。有什么想法吗?我试着突破

我不明白为什么nginx在location语句之前执行If语句。 更准确地说,为什么nginx不执行return语句,然后停止处理

即使$http\u x\u forwarded\u host不是因为if语句位于location语句下面,我也希望如果我打开/xyz,会得到一个带有“hello world”的200。但是nginx只是忽略了location语句,并遇到了if子句。有什么想法吗?我试着突破
    server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;
    index   index.html index.htm index.php;
    
        location /xyz {
          return 200 'hello world';

        }

        if ($http_x_forwarded_host != "www.acme.com") {
                return 301 https://www.acme.com$uri;
        }


    }


我认为这是因为重定向后,它再次到达您的站点。可能重定向指向与位置相同的主机?

您是对的,所有来自的指令都是在位置选择机制就位之前执行的。使用
break
指令意味着从重写模块中断这些指令的执行,并根据最佳匹配位置立即强制执行请求。这是因为尽管nginx配置通常是声明性的,但重写模块必须对其指令进行评估。对于每个nginx新手来说,这总是一个困惑的来源。您可以阅读有关重写模块内部实现的更多信息

也就是说,您不能在配置中实现这种行为。这并不意味着你根本无法实现你想要的,一个可能的解决方案是使用regex负前瞻功能:

if($http\u x\u转发的\u主机!=“www.acme.com”){
#仅当URI不以“/xyz”开头时才执行重定向
重写^(?!/xyz)https://www.acme.com$uri永久性;
}
位置/xyz{
返回200个“你好世界”;
}
如果要执行一些复杂的请求处理而不是重定向,可以使用以下位置:

if($http\u x\u转发的\u主机!=“www.acme.com”){
#如果以后需要原始URI,可以保存其值
#设置$original_uri$uri;
#仅当URI不以“/xyz”开头时,才使用特殊位置处理请求
重写^(?)/xyz)/special;
}
位置/xyz{
返回200个“你好世界”;
}
地点/特别{
内部的;
…#此处的任何自定义处理,例如“return 403;”
}

显然,对于这样的位置,您应该选择一个URI前缀,而不是以任何方式干扰您现有的站点。

谢谢@Ivan,我会尝试并给出反馈。效果很好。您知道是否可以执行相同的逻辑,但发送403而不是重定向。但是那只狗/xyz异常应该保留在那里。我找不到办法,因为“return403”不需要正则表达式。谢谢你,伊万-这对我来说很有魅力。回答得很好。