Как сделать вложенные условия if в nginx

На неделе программисты сайта на работе поставили задачу — надо было настроить редирект на сайте, но при этом, редирект должен был происходить при одновременном выполнении двух условий. Но, с этим то как раз в nginx'е беда — он не понимает и не разрешает делать вложенные блоки if. Ежели в конфигурацию добавить подобную конструкцию(привожу в качестве примера), то nginx с ней не запустится:

1
2
3
4
5
6
7
8
9
      location / {
          if ($request_uri ~* \?rsd) {
              if ($request_method = POST) {
                  return     301 https://www.baf.ru$uri;
                  break;
              }
          }
          proxy_pass         http://127.0.0.1;
      }
1
2
3
# nginx -t
nginx: [emerg] "if" directive is not allowed here in /etc/nginx/conf.d/baf.ru.conf:317
nginx: configuration file /etc/nginx/nginx.conf test failed

Казалось бы — проблема не решаемая. Но после чтения документации и форумов, оказалось, что проверку по нескольким условиям в nginx сделать можно. Получаемый при этом код в конфигурации принимает следующий вид:

1
2
3
4
5
6
7
8
9
10
                  set $ax 0;
                  if ($request_uri !~* /ajax/) {
                      set $ax 1;
                  }
                  if ($request_method != POST ) {
                      set $ax "${ax}1";
                  }
                  if ($ax = "11") {
                      rewrite         ^/(.*)(index\.php)$ https://site.ru/$1 permanent;
                  }

Как работает «код» приведённый выше? В строке №1 определяется переменная и ей присваивается 0 значение, то есть false. Далее, ежели у нас выполняется условие в строке №2, то мы этой переменной присваиваем значение 1. Ежели у нас выполняется условие в строке №5, тогда nginx в переменную $ax конкатенирует текущее значение переменной $ax и 1. В конечном итоге, в строке №8 мы проверяем значение переменной $ax, и в зависимости от её значения, выполняем или нет код в этом блоке.

Ежели у нас выполнится только первое условие, а второе нет — значением переменной будет «1». Ежели выполнится второе условие, а первое нет — то значением переменной будет «01». И только когда выполнятся оба условия, значением переменной будет «11».

Таким образом, можно организовать проверку по нескольким условиям, и результат этих проверок собрать в одной переменной. После чего, можно спокойно принять решение — что делать или не делать, в зависимости от того, что будет в значении переменной. Получается несколько громоздко — но другого способа я пока не знаю.

Categories: UNIX
Tags: nginxunix
admin:

View Comments (1)

  • другой и более удобны способ использовать map . https://habr.com/ru/post/231277/
    Если бы не условия тестового задания не использовать map, то я бы сюда не попал))

Related Post