【问题标题】:How can I add header conditionally in nginx configuration?如何在 nginx 配置中有条件地添加标头?
【发布时间】:2015-06-10 15:18:50
【问题描述】:

如何在 nginx(1.4.6 ubuntu) 配置中有条件地添加标头?

一开始我是这样尝试的。

 location / {
      add_header X-TEST-0 always-0;

      set $true 1;
      if ($true) {
          add_header X-TEST-1 only-true;
      }

      add_header X-TEST-2 always-2;
  }    

虽然我希望我的 nginx 设置所有标头(X-TEST-0,1,2),但它只添加了标头 X-TEST-1。

接下来我是这样尝试的。

 location / {
      add_header X-TEST-0 always-0;

      ##set $true 1;
      ##if ($true) {
      ##    add_header X-TEST-1 only-true;
      ##}

      add_header X-TEST-2 always-2;
  }    

我的 nginx 按我的预期添加了标头 X-TEST-1 和 X-TEST-2。

我的问题是……

  1. 如何有条件地添加标题?

  2. 为什么 nginx 在我上面的第一个示例中只添加 X-TEST-1?

提前致谢!

【问题讨论】:

  • 这是If is evil的经典例子
  • 您可以在if 中使用set。或者使用map 指令。
  • 感谢您提供的信息!我可以在你链接的页面中得到我想要的一切。
  • 使用map,如serverfault.com/a/598106/119913中所述
  • 感谢@KevinSmyth!我稍后会尝试。

标签: nginx


【解决方案1】:

我是这样解决的,我想打印一个指定的国家符号 首先,如果服务器中的某些 IP 阻塞,我会映射 geo

geo $CNTRY {
    default '';
    192.104.49.0/24 ML;
    192.104.46.0/24 ML;
    192.104.47.0/24 ML;
}

然后我只需将它添加到服务器块,(任何地方都无所谓)

add_header x-CNTRY $CNTRY;

【讨论】:

    【解决方案2】:

    如果您有不同的想法并使用地图,这很简单。

    map $variable  $headervalue {
        1        only-true;
        default  '';
    }
    
    # ...later...
    location / {
        add_header X-TEST-1   $headervalue;
    }
    

    如果 $variable 为 1,$headervalue 将被设置,因此 header 将被添加。 默认情况下 $headervalue 将为空,并且不会添加标题。

    这是有效的,因为 Nginx 仅在需要时评估映射(当它到达引用 $headervalue 的点时)。

    查看类似内容:https://serverfault.com/questions/598085/nginx-add-header-conditional-on-an-upstream-http-variable

    【讨论】:

    • 我认为重要的是添加地图仅在 http 上下文中有效。我在服务器上下文中使用它(就在 location 指令的正上方)并收到关于 "map" directive is not allowed here 的错误。 nginx.org/en/docs/http/ngx_http_map_module.html#map
    【解决方案3】:

    (我会为将来有同样问题的人写这个结论。感谢@Alexey Ten提供的信息。)

    结论:

    不要在if 指令中使用任何非重写指令。 因为if 指令本质上是重写模块的一部分。

    我们可以在名为IfIsEvil的官方文档中获得更多详细信息。

    【讨论】:

    • @siddhusingh 如果这个问题的需求量很大,那你为什么不投票呢?!
    • 就是这样做的。抱歉,我不太习惯这里的这些投票概念。如果我喜欢这个答案,我会投票,但通常也会忘记投票。从现在开始我会这样做。
    • 这可能不是正确的答案,但它帮助我解决了与缺少响应标头有关的问题
    【解决方案4】:

    我用lua nginx module解决了类似的问题:

    localtion / {
      header_filter_by_lua_block {
        ngx.header["X-TEST-0"] = "always-0";
        # example of conditional header
        if ngx.req.get_method() == ngx.HTTP_POST {
          ngx.header["X-TEST-1"] = "only if POST request";
        }
        ngx.header["X-TEST-2"] = "always-2";
      }
    }    
    

    https://github.com/openresty/lua-nginx-module#header_filter_by_lua_block ```

    【讨论】:

    • 感谢您提供有用的信息。对于不介意使用非 nginx 标准模块的 nginx 用户来说,这可能是一个解决方案。我投票 +1。
    • 如果有人在尝试这样的事情,请注意正确的 lua 语法可能是 if ... then ... end :-)
    猜你喜欢
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 2012-11-15
    • 1970-01-01
    • 2016-10-28
    • 2020-04-27
    • 1970-01-01
    相关资源
    最近更新 更多