EAimTY的博客
一个没什么技术的开源爱好者,一个苦逼的学生狗。

Nginx有个好:config写起来比Apache舒服多了。

但是,很多情况下,我们的需求可能会稍稍有些复杂,一个很常见的场景就是需要涉及到多个判断条件。

那么,我们该如何实现呢?

我们首先试试如何实现AND,即两条件同时成立时才执行代码块内容。

Nginx中的if/else的语法如下:

if (<condition>) {
    <code>;
} else {
    <code>;
}

为了方便,下面就不再写else了。

使用逻辑运算符连接两条件

尝试像大多数语言标准一样,在多个条件间用逻辑运算符连接。

if (<condition1> AND <condition2>) {
    <code>;
}

nginx -t测试一下,结果报错……智障Nginx并不知道AND是什么……
试试用符号?

if (<condition1> && <condition2>) {
    <code>;
}

还是有问题,看来Nginx并不支持逻辑运算符。

使用多个if块嵌套

真是出师不利……那试试曲线救国吧。

if (<condition1>) {
    if (<condition2>) {
        <code>;
    }
}

大概意思是在condition1成立时判断condition2是否成立,若成立则执行<code>;
运行测试,又是报错,大体意思是说第二个if不应该出现在这里,简单点解释就是Nginx并不支持if的嵌套……

引入变量存储条件状态

之前的两次尝试都失败了,那么这多条件判断到底应该怎么实现呢?
Google了一些资料和文章后,发现最简单的方法就是引入一个新变量。

首先是OR,即“或”的实现方式:

set $foo 0;
if (<condition1>) {
    set $foo 1;
}
if (<condition2>) {
    set $foo 1;
}
if ($foo = 1) {
    <code>;
}

只要两个条件中有任意一个成立,$foo就会被赋值为1,最后一个代码块就会被执行。

AND,即“与”的实现方式:

set $foo "";
if (<condition1>) {
    set "${foo}1";
}
if (<condition2>) {
    set "${foo}1";
}
if ($foo ~* "11") {
    <code>;
}

首先把$foo清空,之后每当有一个条件成立,就会在$foo的结尾添加一个1,当$foo中的字符串为“11”时,最后的代码块会被执行。

多个“与”或“非”自由组合:

set $foo "";
if (<condition1>) {
    set $foo "1";
} else {
    set $foo "0";
}
if (<condition2>) {
    set $foo "${foo}1";
} else {
    set $foo "${foo}0";
}
if (<condition3>) {
    set $foo "${foo}1";
} else {
    set $foo "${foo}0";
}

……

if ( $foo ~* "011" ) {
    <code>;
}

刚开始是$foo是空字符串,每当一个判断成立时$foo的最后会被添加一个1,不成立则添加0,以此类推,最后一个if块中$foo要匹配的字符串就是你希望实现的判断。

Nginx的变量字符匹配中,~*代表匹配,!~*代表不匹配(实际上都是正则)

说了这么多,这些能干什么?

举个例子,当我们直接用Nginx给Google Analytics发送数据时,一般需要考虑两个条件:

  • 是否是爬虫
  • 用户是否开启DNT(Do Not Track)

这时多条件判断就派上用场了。

类似的使用环境有很多,这里就不一一列举了。

已有 2 条评论
    卢本伟
    卢本伟
    2018-04-10 14:25

    备案略屌

    老李
    老李
    2018-04-19 14:53

    我也觉得

添加新评论