如果条件在nginx conf中的位置块内工作怎么办?

时间:2016-02-07 19:23:06

标签: nginx nginx-location

我读过 https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/

我想检查我的rails应用程序是否已添加标题(Access-Control-Allow-Origin),如果没有,则添加标题。

这里的示例试图解释nginx.conf http://agentzh.blogspot.in/2011/03/how-nginx-location-if-works.htmlif条件的行为

但我还没明白。我的问题之一是当他们说出指令或阶段指令时意味着什么?

我自己尝试过一些东西。像:

location / {
  add_header My-outer-header '*';
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true; 

  if($sent_http_access_control_allow_origin != /*){
    add_header My-inner-header '**';
  }
}

如果满足if条件,则仅设置My-inner-header而不是My-outer-header

但是当我这样做时:

location / {
  add_header My-outer-header '*';
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true; 
  set $a 1;
  if($a == 1){
    add_header My-inner-header '**';
  }
}

这里$ a变量设置为1,但只有My-inner-header再次设置,而不是My-outer-header

我想检查并确保proxy_set_header之类的说明是否正在执行。

1 个答案:

答案 0 :(得分:4)

我还没有测试过您的代码。我只是从经验中说话!!!

首先,请允许我指定Nginx配置与任何OOP行为(面向对象编程)完全不相似。它是一个单词不可预测的"声明"。

含义......如果在同一个块中有2个IF语句都满足条件,则只有第二个将占优势并执行。

同样的情况发生在同一个块中的1个if和所有它之前的声明。由于存在IF,一些变量(并非全部)将不会被执行,并且nginx期望它们在其中被重新声明。 这在您的示例中发生。为清楚起见,我们采取第二个。 在您的位置块内,您声明了几个标头值。但是,当满足IF语句时,它们不会被执行(IF在nginx中确实是邪恶的)。为了完全执行,你需要在if语句中再次声明大部分头部变量和if之外的任何其他内容,以便在满足if语句的情况下执行它们。注意,没有映射列出nginx中受IF影响的所有变量,你应该测试我们的conf是否有任何错误。某些变量不需要重新声明,在这种情况下,nginx将在重新启动时报告错误。只有这样才能弄清楚哪一个是为了所有人,并排除报告的错误行为。

建议

a)尽可能避免在nginx中使用IF。请改用位置块。 例如如果您只是想为某些文件添加类似Access-Control-Allow-Origin的标头变量,请不要使用if,而是使用第二个位置块(见下文)

location / {
  // some code here
}
location ~* \.(eot|ttf|woff|woff2)$ {
    add_header Access-Control-Allow-Origin *;
}

b)如果IF是强制性的,请谨慎使用并进行测试测试。如上所述,在if语句中重新声明所有内容是一种很好的做法(如上所述,测试并排除任何重新声明中断配置)。

祝你好运。