sub_filter în Nginx

Reverse proxy și load balancing Toate versiunile Nginx (mai multe sub_filter în același bloc: 1.9.4+); modulul ngx_http_sub_module

Înlocuiește un text în răspunsul trimis clientului, de exemplu adrese vechi din HTML-ul unei aplicații din spatele proxy-ului.

Sintaxă
sub_filter 'text_vechi' 'text_nou';
sub_filter_once on | off;
sub_filter_types tip_mime ...;
sub_filter_last_modified on | off;

Ce face sub_filter

sub_filter caută un text în corpul răspunsului și îl înlocuiește înainte de a-l trimite browserului. Este util când o aplicație din spatele proxy-ului scrie adrese absolute greșite (http://localhost:8080) sau când vrei să injectezi un script într-o pagină pe care nu o poți modifica.

Implicit se înlocuiește doar prima apariție (sub_filter_once on) și doar în răspunsurile text/html. Pentru CSS, JavaScript sau JSON adaugă tipurile în sub_filter_types.

Modulul nu este compilat implicit (opțiunea --with-http_sub_module), dar este inclus în pachetele de pe nginx.org și din Debian/Ubuntu. Înlocuirea merge doar pe răspunsuri necomprimate: când serverul din spate trimite gzip, cere-i răspunsul necomprimat cu proxy_set_header Accept-Encoding "";.

Parametri

Parametru Descriere
Context http, server, location.
sub_filter text nou Textul căutat și înlocuirea; înlocuirea poate conține variabile.
sub_filter_once Implicit on: doar prima apariție. off = toate aparițiile.
sub_filter_types Implicit text/html. Alte tipuri MIME de prelucrat (* = toate).
sub_filter_last_modified Implicit off: antetul Last-Modified este eliminat, pentru că răspunsul s-a schimbat.

Ce returnează

Răspunsul cu textul înlocuit.

Exemple

Exemplul 1: Adrese interne înlocuite cu domeniul public

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header Accept-Encoding "";

    sub_filter 'http://127.0.0.1:8080' 'https://$host';
    sub_filter_once off;
    sub_filter_types text/css application/javascript application/json;
}

Exemplul 2: Injectarea unui script de statistici

Aici sub_filter_once rămâne on: </head> apare o singură dată în pagină.

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Accept-Encoding "";

    sub_filter '</head>' '<script defer src="/statistici.js"></script></head>';
}

Exemplul 3: Verifică dacă modulul există

nginx -V 2>&1 | grep -o with-http_sub_module

Ieșire în terminal

with-http_sub_module

Greșeli frecvente

  • Înlocuirea nu are efect pentru că serverul din spate trimite răspunsul comprimat cu gzip. Adaugă proxy_set_header Accept-Encoding "";.
  • Uiți sub_filter_once off; și se înlocuiește doar prima adresă din pagină.
  • Folosești sub_filter pentru modificări mari sau pe răspunsuri foarte mari: fiecare răspuns este parcurs caracter cu caracter. Corectarea aplicației (de exemplu setarea adresei publice în configurația ei) este soluția mai bună.