nginx njs: instalacja modułu, ustawienie js_set i zastosowanie przez reload, aby tworzyć zmienne JavaScript

nginx njs to oficjalny moduł nginx, który w konfiguracji nginx obsługuje żądania lub tworzy wartości zmiennych funkcjami JavaScript. Na serwerze z Nginx + Apache, aby ujednolicić wielkość liter w adresach żądań, czego sama konfiguracja nginx nie zmieni, zainstalowano moduł njs w tej samej wersji co zainstalowany nginx, a zmienną utworzoną przez js_set wstawiono do ścieżki pliku cache i zastosowano przez reload, bez restartu.
Przykładowa funkcja to jedna linijka, która zamienia na małe litery kodowanie procentowe koreańskich adresów, a tworzenie zmiennych przez odczyt nagłówków lub wartości argumentów z obiektu żądania działa tak samo.
1️⃣ Czym jest nginx njs: moduł rozszerzający nginx o JavaScript
njs nie jest samodzielnym środowiskiem uruchomieniowym JavaScript jak Node.js: nie ma skryptu startowego ani własnej pętli zdarzeń, a kod działa tylko wtedy, gdy nginx wywoła funkcję wskazaną w konfiguracji, po czym przetwarzanie wraca do nginx.
Miejsca, w których nginx wywołuje funkcje JavaScript, są ustalone: fazy przetwarzania żądań i odpowiedzi HTTP, fazy przetwarzania sesji TCP/UDP, obliczanie wartości zmiennych i okresowe timery. Funkcja czyta adres, nagłówki i argumenty z obiektu żądania przekazanego przez nginx i zwraca wynik jako odpowiedź lub wartość zmiennej.
Po stronie HTTP [js_import] wczytuje plik skryptu, [js_set] tworzy wartość zmiennej, [js_content] tworzy treść odpowiedzi, a [js_header_filter] i [js_body_filter] przerabiają nagłówki i treść odpowiedzi. W tej konfiguracji użyto dwóch dyrektyw: [js_import] i [js_set].
Domyślny silnik modułu njs implementuje ECMAScript 5.1 (strict mode) oraz część funkcji ECMAScript 6 i nowszych. Obróbka tekstu na poziomie zamiany wyrażeniem regularnym i funkcji działa w tym zakresie.
2️⃣ Kiedy potrzebujesz njs: wartości zmiennych, których sama konfiguracja nginx nie zmieni
Wtyczka WordPress WP Rocket nazywa foldery cache wpisów z koreańskimi adresami kodowaniem procentowym małymi literami, a przeglądarki żądają tego samego adresu zakodowanego wielkimi literami. Na tym serwerze działa strona WordPress.
Jeśli nginx buduje ścieżkę pliku cache z adresu żądania bez zmian, wielkość liter się nie zgadza, plik nie zostaje znaleziony, a żądanie przechodzi do Apache i PHP.
Sama konfiguracja nginx nie zamieni tej wartości na małe litery. [map] tylko wybiera jedną z ustawionych wartości i nie przekształca tekstu, a przed instalacją ani wyjście [nginx -V], ani folder modułów nie pokazywały modułu perl czy lua.
Jeśli zmienić trzeba tylko kilka adresów, wystarczy tabela [map], ale przy każdym nowym wpisie trzeba ją odtworzyć i zrobić reload. Gdy każdy adres ma mieć własną wartość zamienioną według tej samej zasady, jedna funkcja [js_set] obejmuje też nowe wpisy, tagi i adresy kategorii.

W tym samym miejscu można użyć [perl_set] z modułu perl, a repozytorium ma pakiet dopasowany do nginx, ale oficjalna dokumentacja nginx opisuje moduł perl jako eksperymentalny.
3️⃣ Instalacja nginx njs: w tej samej wersji co zainstalowany nginx
Instalacja samą nazwą pakietu wygląda tak, jakby dodawała tylko njs, ale najnowszy njs w repozytorium wymaga najnowszego nginx, więc nginx też zostaje zaktualizowany. Przy sprawdzeniu przed instalacją polecenie bez wersji pokazało plan podniesienia nginx z 1.28.0 do 1.30.6.
Dlatego zacznij od sprawdzenia, jaka wersja nginx jest teraz zainstalowana.
rpm -q nginxnginx-1.28.0-1.el9.ngx.x86_64Repozytorium ma osobny pakiet njs dopasowany do każdej wersji nginx; w numerze wersji część przed + to wersja nginx, a po nim wersja njs.
dnf list --showduplicates nginx-module-njs | grep '1.28.0+'nginx-module-njs.x86_64 1:1.28.0+0.9.4-1.el9.ngx @nginx-stable
nginx-module-njs.x86_64 1:1.28.0+0.8.10-1.el9.ngx nginx-stable
nginx-module-njs.x86_64 1:1.28.0+0.9.0-1.el9.ngx nginx-stable
nginx-module-njs.x86_64 1:1.28.0+0.9.1-1.el9.ngx nginx-stable
nginx-module-njs.x86_64 1:1.28.0+0.9.2-1.el9.ngx nginx-stable
nginx-module-njs.x86_64 1:1.28.0+0.9.3-1.el9.ngx nginx-stable
nginx-module-njs.x86_64 1:1.28.0+0.9.4-1.el9.ngx nginx-stableDo nginx 1.28.0 pasuje sześć wersji, od 0.8.10 do 0.9.4, a górny wiersz @nginx-stable to wersja już zainstalowana. Zainstaluj najnowszą z nich, 0.9.4, podając pełny numer wersji.
dnf install nginx-module-njs-1:1.28.0+0.9.4-1.el9.ngxZa pomocą rpm sprawdzisz, jakiej wersji nginx wymaga zainstalowany pakiet.
rpm -q --requires nginx-module-njs | grep nginxnginx-r1.28.0rpm -ql nginx-module-njs | grep -v build-id/usr/bin/njs
/usr/lib64/nginx/modules/ngx_http_js_module-debug.so
/usr/lib64/nginx/modules/ngx_http_js_module.so
/usr/lib64/nginx/modules/ngx_stream_js_module-debug.so
/usr/lib64/nginx/modules/ngx_stream_js_module.so
/usr/share/doc/nginx-module-njs
/usr/share/doc/nginx-module-njs/CHANGES
/usr/share/doc/nginx-module-njs/COPYRIGHTZainstalowane pliki to moduł HTTP, moduł stream obsługujący TCP/UDP, wersja debugowa każdego z nich i narzędzie wiersza poleceń njs. Ta konfiguracja wczytuje tylko jeden plik, moduł HTTP [ngx_http_js_module.so].
4️⃣ Ustawienie js_set: od wczytania modułu do ścieżki pliku cache
Instalacja pakietu nie sprawia, że nginx sam wczyta moduł: na samej górze nginx.conf musi być wiersz [load_module]. Według oficjalnej dokumentacji [load_module] to dyrektywa kontekstu main, więc stoi poza blokami events i http.
# góra /etc/nginx/nginx.conf (poza blokami events i http)
load_module modules/ngx_http_js_module.so;Funkcja zamiany leży w osobnym pliku .js, oddzielnie od plików konfiguracji, a konfiguracja nginx importuje funkcję wyeksportowaną przez export default w ostatnim wierszu.
// /etc/nginx/njs/rocket.js — tylko kodowanie procentowe %XX na małe litery
function lc(r) {
return r.variables.request_uri.replace(/%[0-9A-F]{2}/g, function (m) { return m.toLowerCase(); });
}
export default { lc };Funkcja czyta zmienną [request_uri] z obiektu żądania r, zamienia na małe litery tylko dwa znaki po każdym znaku procentu tam, gdzie są wielkie, i zwraca wynik. Litery łacińskie zostają bez zmian, więc angielskie adresy z wielkimi literami się nie zmieniają; to ta sama zasada, według której WP Rocket nazywa foldery cache.
# wewnątrz bloku http (plik .conf w conf.d)
js_import rkt from /etc/nginx/njs/rocket.js;
js_set $rocket_uri rkt.lc;W [js_import] rkt to nazwa, którą wywołuje się funkcje z modułu, a [js_set] zamienia wynik tej funkcji w zmienną [$rocket_uri]. Według oficjalnej dokumentacji funkcja uruchamia się przy pierwszym odwołaniu do zmiennej w żądaniu i obsługuje tylko przetwarzanie synchroniczne.
# blok server — $request_uri w ścieżce pliku cache zmienia się na $rocket_uri
set $rocket_file '/wp-content/cache/wp-rocket/example.com${rocket_uri}index$rocket_mobile-https.html';Zmienia się tylko ten jeden wiersz budujący ścieżkę pliku cache; sprawdzenia, które wykluczają z cache ciasteczka logowania, zapytania i żądania POST, zostają bez zmian.
5️⃣ Zastosowanie i sprawdzenie: log błędów i nagłówki odpowiedzi po reloadzie
Najpierw uruchom test konfiguracji, a jeśli przejdzie, zrób reload.
nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulsystemctl reload nginxNowy wiersz [load_module] zadziałał po reloadzie, bez restartu. Log błędów zapisał wiersz o inicjalizacji maszyny wirtualnej njs i nie było błędów JavaScript.
grep 'js vm init' /var/log/nginx/error.log | head -12026/10/17 18:21:35 [notice] 27992#27992: js vm init njs: 0000559FDF6D0E00njs na końcu wiersza to nazwa używanego silnika. Ten sam wiersz zapisuje się też przy teście konfiguracji przez [nginx -t], więc porównaj go z godziną reloadu.
curl -sI 'https://example.com/-/' | grep -i 'x-rocket\|content-type'content-type: text/html
x-rocket-nginx-serving-file: HITNawet przy koreańskim adresie zakodowanym wielkimi literami pojawił się nagłówek pokazujący, że nginx podał plik cache. Żądania z zapytaniami lub ciasteczkami logowania oraz żądania POST po zmianie nadal szły do PHP bez tego nagłówka.
6️⃣ Wycofanie njs i aktualizacja nginx
Aby wycofać zmianę, zamień [$rocket_uri] w ścieżce pliku cache z powrotem na [$request_uri], usuń plik konfiguracji z [js_import]/[js_set] i wiersz [load_module], a potem uruchom test konfiguracji i zrób reload.
# blok server — powrót do pierwotnej zmiennej
set $rocket_file '/wp-content/cache/wp-rocket/example.com${request_uri}index$rocket_mobile-https.html';Pakiet możesz zostawić: bez wiersza [load_module] nginx go nie wczyta, więc usuwaj pakiet tylko wtedy, gdy chcesz pozbyć się go całkowicie.
dnf remove nginx-module-njsPrzy aktualizacji nginx pakiet njs musi razem z nim przejść na wersję dopasowaną do nowego nginx. Przed aktualizacją sprawdź przez [dnf list --showduplicates], czy repozytorium ma odpowiednik njs dla nowej wersji nginx.
🔢 FAQ & polecane treści














ℹ️ Informacja o linkach partnerskich
Treści tej witryny zawierają linki partnerskie. Jeśli odwiedzający kupi produkt lub usługę przez taki link, witryna otrzymuje od sprzedawcy prowizję. Kwota płacona przy tym przez kupującego (podczas promocji spada↓) nie wzrasta. Podane ceny, rabaty i dostępność odnoszą się do chwili pisania i mogą różnić się od stanu faktycznego, dlatego przed zakupem sprawdź je u sprzedawcy. Produkty wybieramy i oceniamy według własnych kryteriów, a prowizja nie wpływa ani na kolejność prezentacji, ani na treść ocen.

