首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nginx -嵌套if与查询参数

Nginx -嵌套if与查询参数
EN

Stack Overflow用户
提问于 2016-11-21 09:13:21
回答 1查看 357关注 0票数 1

这就是我需要做的:

  • 检查请求是否来自facebook
  • 使用我接收的参数重定向url作为查询参数。
  • 如果url不是来自facebook,则返回普通页面

我使用以下配置:

代码语言:javascript
复制
location / {
            if ($args ~* "^param-1=(.*)&param-2=(.*)") {
                    set $paramVar "1";
                    set $args2 $2;
            }
            if ($http_user_agent ~* (facebookexternalhit)) {
                    set $paramVar "${paramVar}1";
            }
            if ($paramVar = "11") {
                    rewrite ^.*$ https://www.example.com/$args2? last;
            }
            root /usr/share/nginx/html/xyz;
            try_files $uri /index.html;
}

这在从facebook共享调试器调用时很好,但是普通调用返回404。我认为这是因为一个正常的调用满足了第一个调用,但失败了第二个调用。

我知道“IFISEVIL”,但在这种情况下是否有办法避免使用它。

EN

回答 1

Stack Overflow用户

发布于 2021-08-05 19:52:06

首先,您的示例不是“嵌套If”。如果是的话,那看起来就像

代码语言:javascript
复制
if ($cond1) {
   if ($cond2) {
     ...
   }
 ...
}

那在Nginx是违法的..。

但是,通过使用Maps,您可以避免配置中的额外"ifs“。

地图逻辑基本上是(伪代码):

代码语言:javascript
复制
if $condtion1 = <param1> then set $var1 = <value1>
else if $condition1 = <param2> then set $var1 = <value2>
... <paramN> ... <valueN>
else set $var1 = <defaultValue>

使用Nginx配置中的Http上下文中提供Global的几个映射,您可以执行如下操作:

代码语言:javascript
复制
# if ($args ~* "^param-1=(.*)&param-2=(.*)") {
#      set $paramVar "1";
#      set $args2 $2;
# }
### Your logic reduces to: if query params begin with param-1=someVal
### then set $args2 = $2

### here is the equivalent map: 
map $args $param_1 {
    default "";
    ^~param-1&param-2 $args2;
}

### now let's detect that fb external hit
map $http_user_agent $fb_route {
    
    ~*facebookexternalhit 1;
    default 0;
}

### set $do_rw = 1 to implement our IF later using clean code
### note that Nginx is doing a literal concat of the 2 mapped vars
### thus "11" below means $param_1 = 1 AND $fb_route = 1
map $param_1$fb_route $do_rw {
    
    11 1;
    default 0;
}

生成的单个"If“指令被放置在Server或Location上下文中:

代码语言:javascript
复制
### note that because $args2 and $do_rw are Global
### the following works:
if ($do_rw) {
  rewrite ^.*$ https://www.example.com/$args2? last; 
}

对于最终的生产代码和最佳实践,我可以做一些呼吁,但是我已经尝试完全复制您的代码,就像它所暗示的那样,只在直接地图实现和"if's“之间减少它。

请注意,Maps确实有性能影响,但比"if's“要小,而且Maps比"if's”更干净。使用Maps,您还可以利用这些全局Vars设置一次,并可能消耗多个虚拟主机,如果您使用SNI.

最后--有点超出了OP的范围--我可以使用Ngx_lua模块来消除If完全在这个配置中.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40716426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档