if în Nginx

Redirecționări și rescrieri Toate versiunile Nginx

Execută directive doar când o condiție este adevărată. În location este sigur doar cu return și rewrite ... last; în rest, folosește map sau blocuri separate.

Sintaxă
if (condiție) {
    return ...;   # sau rewrite ... last;
}

# condiții: $var   $var = text   $var != text   $var ~ regex   $var ~* regex
#           -f fișier   !-f fișier   -d   -e   -x

Ce face if

if face parte din modulul rewrite și verifică o condiție la fiecare cerere: o variabilă nevidă, o comparație (=, !=), o expresie regulată (~ sensibilă la majuscule, ~* fără) sau existența unui fișier (-f, -d, -e).

if nu este un „if” ca în limbajele de programare: în interiorul unui location creează intern un bloc de configurație separat, care moștenește directivele într-un mod greu de prevăzut. Documentația Nginx („If is Evil”) spune că singurele utilizări sigure în location sunt return ...; și rewrite ... last;. Alte directive (de exemplu try_files, add_header, proxy_pass) pot avea efecte neașteptate.

Nu există else, && sau ||. Pentru alegeri după o valoare, map (în blocul http) este mai clar și mai sigur; pentru domenii diferite, folosește blocuri server separate.

Parametri

Parametru Descriere
Context server, location.
$variabila Falsă dacă este text gol sau "0".
= / != Comparație exactă cu un text.
~ / ~* / !~ / !~* Potrivire cu expresie regulată (cu sau fără diferență de majuscule).
-f / -d / -e / -x Fișierul există / directorul există / există orice / este executabil (cu ! pentru negație).

Ce returnează

Nimic; directivele din bloc se aplică doar dacă condiția este adevărată.

Exemple

Exemplul 1: Utilizare sigură: pagină de mentenanță

Când fișierul mentenanta.html există, toate cererile primesc 503 cu pagina de mentenanță. Ștergi fișierul și site-ul revine.

server {
    # ...
    if (-f $document_root/mentenanta.html) {
        return 503;
    }

    error_page 503 /mentenanta.html;
    location = /mentenanta.html {
        internal;
    }
}

Exemplul 2: map în loc de mai multe if-uri

Logica de alegere stă în map; în location rămâne doar un if cu return, care este sigur.

# ÎN LOC DE:
# location / {
#     if ($http_user_agent ~* "(curl|wget|python-requests)") {
#         set $limitat 1;
#     }
#     ...
# }

# FOLOSEȘTE map în blocul http:
map $http_user_agent $client_automat {
    default                          0;
    ~*(curl|wget|python-requests)    1;
}

server {
    # ...
    location /api/ {
        if ($client_automat) {
            return 429;
        }
        proxy_pass http://127.0.0.1:8080;
    }
}

Exemplul 3: Nu există else

Configurația conține un bloc else { ... } după un if.

sudo nginx -t

Ieșire în terminal

nginx: [emerg] unknown directive "else" in /etc/nginx/sites-enabled/exemplu.ro.conf:14
nginx: configuration file /etc/nginx/nginx.conf test failed

Greșeli frecvente

  • Scrii if ($host = www.exemplu.ro) { return 301 ...; } într-un server care răspunde pentru ambele domenii. Un bloc server separat pentru www este mai clar și se evaluează mai rapid.
  • Pui try_files sau proxy_pass într-un if din location și cererile ajung unde nu te aștepți. Păstrează în if doar return și rewrite ... last.
  • Scrii o expresie regulată care conține } sau ; fără ghilimele: documentația cere ca toată expresia să fie pusă între ghilimele, altfel nginx -t dă eroare de sintaxă.

Comenzi înrudite

  • set: Creează sau schimbă o variabilă în configurația Nginx. Valoarea poate combina text și alte variabile.