nginx njs: instalar el módulo, configurar js_set y aplicar un reload para crear variables de JavaScript

nginx njs es un módulo oficial de nginx que procesa peticiones o crea valores de variables con funciones de JavaScript dentro de la configuración de nginx. En un servidor con Nginx + Apache, para igualar las mayúsculas y minúsculas de las URL de las peticiones, algo que la configuración de nginx sola no puede cambiar, se instaló el módulo njs en la misma versión que el nginx instalado, se puso una variable creada con js_set en la ruta del archivo de caché y se aplicó con un reload, sin reiniciar.
La función de ejemplo es de una sola línea y pasa a minúsculas la codificación porcentual de las URL en coreano; crear variables leyendo cabeceras o argumentos del objeto de petición funciona igual.
1️⃣ Qué es nginx njs: un módulo que amplía nginx con JavaScript
njs no es un entorno de ejecución de JavaScript independiente como Node.js: no tiene script de arranque ni bucle de eventos propio, y el código solo se ejecuta cuando nginx llama a una función indicada en su configuración; después el procesamiento vuelve a nginx.
Los puntos en los que nginx llama a funciones de JavaScript están fijados: las fases de procesamiento de peticiones y respuestas HTTP, las de sesiones TCP·UDP, el cálculo de valores de variables y los temporizadores periódicos. La función lee la URL, las cabeceras y los argumentos del objeto de petición que le pasa nginx y devuelve el resultado como respuesta o como valor de una variable.
En HTTP, [js_import] carga un archivo de script, [js_set] crea el valor de una variable, [js_content] crea el cuerpo de la respuesta y [js_header_filter] y [js_body_filter] modifican las cabeceras y el cuerpo de la respuesta. En esta configuración se usaron dos directivas: [js_import] y [js_set].
El motor predeterminado del módulo njs implementa ECMAScript 5.1 (strict mode) más algunas funciones de ECMAScript 6 y posteriores. El tratamiento de cadenas al nivel de reemplazos con expresiones regulares y funciones funciona dentro de ese alcance.
2️⃣ Cuándo hace falta njs: valores de variables que la configuración de nginx sola no puede cambiar
El plugin de WordPress WP Rocket nombra las carpetas de caché de las entradas con URL en coreano con codificación porcentual en minúsculas, mientras que los navegadores piden la misma URL codificada en mayúsculas. En este servidor funciona un sitio WordPress.
Si nginx construye la ruta del archivo de caché con la URL de la petición tal cual, las mayúsculas y minúsculas no coinciden, no encuentra el archivo y la petición pasa a Apache y PHP.
La configuración de nginx sola no puede pasar este valor a minúsculas. [map] solo elige uno de los valores fijados y no transforma cadenas, y antes de la instalación ni la salida de [nginx -V] ni la carpeta de módulos tenían módulos perl o lua.
Si solo hay unas pocas URL que cambiar, una tabla de correspondencias con [map] sirve, pero hay que rehacerla y hacer reload cada vez que aparece una entrada nueva. Cuando cada URL necesita su propio valor convertido con la misma regla, una sola función con [js_set] cubre también las entradas nuevas, las etiquetas y las URL de categorías.

El [perl_set] del módulo perl también puede usarse en ese punto, y el repositorio tiene un paquete emparejado con nginx, pero la documentación oficial de nginx presenta el módulo perl como experimental.
3️⃣ Instalar nginx njs: en la misma versión que el nginx instalado
Instalar solo con el nombre del paquete parece que añadiría solo njs, pero el njs más reciente del repositorio exige el nginx más reciente, así que también se actualiza nginx. En la comprobación previa, el comando de instalación sin versión mostró un plan para subir nginx de 1.28.0 a 1.30.6.
Por eso, primero se comprueba la versión de nginx instalada.
rpm -q nginxnginx-1.28.0-1.el9.ngx.x86_64El repositorio tiene un paquete njs aparte emparejado con cada versión de nginx; en el número de versión, lo que va antes del + es la versión de nginx y lo de después, la de 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-stableHay seis versiones emparejadas con nginx 1.28.0, de 0.8.10 a 0.9.4, y la línea @nginx-stable de arriba es la ya instalada. La instalación se hace con la más reciente, 0.9.4, escribiendo el número de versión completo.
dnf install nginx-module-njs-1:1.28.0+0.9.4-1.el9.ngxCon rpm puedes ver qué versión de nginx exige el paquete instalado.
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/COPYRIGHTLos archivos instalados son el módulo HTTP, el módulo stream que maneja TCP·UDP, una versión de depuración de cada uno y la herramienta de línea de comandos njs. Esta configuración solo carga un archivo, el módulo HTTP [ngx_http_js_module.so].
4️⃣ Configurar js_set: de cargar el módulo a la ruta del archivo de caché
Instalar el paquete no hace que nginx cargue el módulo automáticamente: nginx.conf necesita una línea [load_module] al principio. Según la documentación oficial, [load_module] es una directiva del contexto main, así que va fuera de los bloques events y http.
# principio de /etc/nginx/nginx.conf (fuera de los bloques events y http)
load_module modules/ngx_http_js_module.so;La función de conversión va en un archivo .js aparte de los de configuración, y la configuración de nginx importa la función exportada con export default en la última línea.
// /etc/nginx/njs/rocket.js — solo la codificación porcentual %XX a minúsculas
function lc(r) {
return r.variables.request_uri.replace(/%[0-9A-F]{2}/g, function (m) { return m.toLowerCase(); });
}
export default { lc };La función lee la variable [request_uri] del objeto de petición r y pasa a minúsculas solo los dos caracteres que siguen a cada signo de porcentaje cuando están en mayúsculas, y devuelve el resultado. Las letras latinas se dejan igual, así que las URL en inglés con mayúsculas no cambian; es la misma regla que usa WP Rocket para nombrar las carpetas de caché.
# dentro del bloque http (un archivo .conf de conf.d)
js_import rkt from /etc/nginx/njs/rocket.js;
js_set $rocket_uri rkt.lc;En [js_import], rkt es el nombre con el que se llaman las funciones del módulo, y [js_set] convierte el resultado de esa función en la variable [$rocket_uri]. Según la documentación oficial, la función se ejecuta cuando la variable se referencia por primera vez en la petición y solo admite procesamiento síncrono.
# bloque server — $request_uri de la ruta del archivo de caché pasa a $rocket_uri
set $rocket_file '/wp-content/cache/wp-rocket/example.com${rocket_uri}index$rocket_mobile-https.html';Lo único que cambia es esta línea que construye la ruta del archivo de caché; las comprobaciones que excluyen de la caché las cookies de sesión, los parámetros y las peticiones POST se quedan igual.
5️⃣ Aplicar y comprobar: registro de errores y cabeceras de respuesta tras el reload
Primero ejecuta la comprobación de la configuración y, si pasa, haz el reload.
nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulsystemctl reload nginxLa nueva línea [load_module] se aplicó con un reload, sin reiniciar. En el registro de errores quedó una línea de inicialización de la máquina virtual de njs, y no hubo errores de JavaScript.
grep 'js vm init' /var/log/nginx/error.log | head -12026/10/17 18:21:35 [notice] 27992#27992: js vm init njs: 0000559FDF6D0E00El njs del final de la línea es el nombre del motor en uso. La misma línea se registra también al comprobar la configuración con [nginx -t], así que contrástala con la hora del reload.
curl -sI 'https://example.com/-/' | grep -i 'x-rocket\|content-type'content-type: text/html
x-rocket-nginx-serving-file: HITIncluso en una URL en coreano codificada en mayúsculas apareció la cabecera que indica que nginx respondió con el archivo de caché. Las peticiones con parámetros o cookies de sesión y las peticiones POST siguieron pasando a PHP sin esa cabecera tras el cambio.
6️⃣ Deshacer njs y actualizar nginx
Para deshacerlo, cambia [$rocket_uri] por [$request_uri] en la ruta del archivo de caché, quita el archivo de configuración con [js_import]·[js_set] y la línea [load_module], comprueba la configuración y haz el reload.
# bloque server — de vuelta a la variable original
set $rocket_file '/wp-content/cache/wp-rocket/example.com${request_uri}index$rocket_mobile-https.html';Puedes dejar el paquete instalado: sin la línea [load_module], nginx no lo carga; quita el paquete solo si quieres eliminarlo del todo.
dnf remove nginx-module-njsAl actualizar nginx, el paquete njs también tiene que subir a la versión emparejada con el nuevo nginx. Antes de actualizar, comprueba con [dnf list --showduplicates] que el repositorio tiene el njs correspondiente a la nueva versión de nginx.
🔢 FAQ & contenido recomendado
















ℹ️ Aviso de afiliados
El contenido de este sitio incluye enlaces de afiliado. Cuando un visitante compra un producto o servicio a través de uno de ellos, el sitio recibe una comisión del vendedor. El importe que paga el comprador(baja durante las promociones ↓)no aumenta. Los precios, descuentos y existencias publicados corresponden al momento de redacción y pueden variar, así que confírmalos con el vendedor antes de comprar. Los productos se eligen y evalúan con criterios propios, y las comisiones no influyen en el orden ni en el contenido de las reseñas.