JS#
El módulo se utiliza para implementar manejadores en njs — un subconjunto del lenguaje JavaScript.
En nuestros repositorios, el módulo se compila
dinámicamente
y está disponible como un paquete separado llamado angie-module-njs o angie-pro-module-njs.
Nota
También está disponible una versión ligera del paquete, llamada ...-njs-light;
sin embargo, no se puede usar junto con la versión regular.
Ejemplo de Configuración#
http {
js_import http.js;
js_set $foo http.foo;
js_set $summary http.summary;
js_set $hash http.hash;
resolver 10.0.0.1;
server {
listen 8000;
location / {
add_header X-Foo $foo;
js_content http.baz;
}
location = /summary {
return 200 $summary;
}
location = /hello {
js_content http.hello;
}
location = /fetch {
js_content http.fetch;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}
location = /crypto {
add_header Hash $hash;
return 200;
}
}
}
El archivo http.js:
function foo(r) {
r.log("hello from foo() handler");
return "foo";
}
function summary(r) {
var a, s, h;
s = "JS summary\n\n";
s += "Method: " + r.method + "\n";
s += "HTTP version: " + r.httpVersion + "\n";
s += "Host: " + r.headersIn.host + "\n";
s += "Remote Address: " + r.remoteAddress + "\n";
s += "URI: " + r.uri + "\n";
s += "Headers:\n";
for (h in r.headersIn) {
s += " header '" + h + "' is '" + r.headersIn[h] + "'\n";
}
s += "Args:\n";
for (a in r.args) {
s += " arg '" + a + "' is '" + r.args[a] + "'\n";
}
return s;
}
function baz(r) {
r.status = 200;
r.headersOut.foo = 1234;
r.headersOut['Content-Type'] = "text/plain; charset=utf-8";
r.headersOut['Content-Length'] = 15;
r.sendHeader();
r.send("nginx");
r.send("java");
r.send("script");
r.finish();
}
function hello(r) {
r.return(200, "Hello world!");
}
async function fetch(r) {
let results = await Promise.all([ngx.fetch('https://example.com/'),
ngx.fetch('https://example.org/')]);
r.return(200, JSON.stringify(results, undefined, 4));
}
async function hash(r) {
let hash = await crypto.subtle.digest('SHA-512', r.headersIn.host);
r.setReturnValue(Buffer.from(hash).toString('hex'));
}
export default {foo, summary, baz, hello, fetch, hash};
Directivas#
js_body_filter#
| |
Predeterminado | — |
location, if in location, limit_except |
Establece una función njs como filtro del cuerpo de la respuesta. La función de filtrado se llama para cada fragmento de datos del cuerpo de la respuesta con los siguientes argumentos:
| el objeto de solicitud HTTP |
| el fragmento de datos entrante, puede ser una cadena o Buffer dependiendo del valor de buffer_type, por defecto es una cadena. |
| un objeto con las siguientes propiedades:
- |
La función de filtrado puede pasar su propia versión modificada del fragmento de datos de entrada al siguiente filtro de cuerpo llamando a r.sendBuffer(). Por ejemplo, para transformar todas las letras minúsculas en el cuerpo de la respuesta:
function filter(r, data, flags) {
r.sendBuffer(data.toLowerCase(), flags);
}
Para detener el filtrado (los siguientes fragmentos de datos serán enviados al cliente sin llamar a js_body_filter), se puede usar r.done().
Si la función de filtrado cambia la longitud del cuerpo de la respuesta, entonces es necesario limpiar la cabecera de respuesta Content-Length (si existe) en js_header_filter para forzar la codificación de transferencia por fragmentos.
Nota
Como el manejador js_body_filter devuelve su resultado de forma inmediata, solo admite operaciones sincrónicas. Por lo tanto, no se admiten operaciones asíncronas como r.subrequest() o setTimeout().
js_content#
| |
Predeterminado | — |
location, if in location, limit_except |
Establece una función njs como manejador de contenido de la ubicación. Se pueden referenciar funciones de módulos.
js_context_reuse#
Establece el número máximo de contextos JS que se reutilizarán para el motor QuickJS. Cada contexto se utiliza para una única solicitud. El contexto finalizado se coloca en un pool de contextos reutilizables. Si el pool está lleno, el contexto se destruye.
js_engine#
Establece el motor JavaScript que se utilizará para los scripts njs. El parámetro njs establece el motor njs, también utilizado por defecto. El parámetro qjs establece el motor QuickJS.
js_fetch_buffer_size#
| |
Predeterminado |
|
http, server, location |
Establece el tamaño del búfer utilizado para leer y escribir con Fetch API.
js_fetch_ciphers#
| |
Predeterminado |
|
http, server, location |
Especifica los cifrados habilitados para conexiones HTTPS con Fetch API. Los cifrados se especifican en el formato entendido por la biblioteca OpenSSL.
La lista de cifrados depende de la versión de OpenSSL instalada.
La lista completa se puede ver utilizando el comando openssl ciphers.
js_fetch_max_response_buffer_size#
| |
Predeterminado |
|
http, server, location |
Establece el tamaño máximo de la respuesta recibida con Fetch API.
js_fetch_protocols#
| |
Predeterminado |
|
http, server, location |
Habilita los protocolos especificados para conexiones HTTPS con Fetch API.
js_fetch_timeout#
Define un tiempo de espera para lectura y escritura para Fetch API. El tiempo de espera se establece solo entre dos operaciones sucesivas de lectura/escritura, no para toda la respuesta. Si no se transmiten datos dentro de este tiempo, la conexión se cierra.
js_fetch_trusted_certificate#
Especifica un archivo con certificados CA de confianza en formato PEM utilizados para verificar el certificado HTTPS con Fetch API.
js_fetch_verify#
Habilita o deshabilita la verificación del certificado del servidor HTTPS con Fetch API.
js_fetch_verify_depth#
| |
Predeterminado |
|
http, server, location |
Establece la profundidad de verificación en la cadena de certificados HTTPS con Fetch API.
js_fetch_keepalive#
| |
Predeterminado |
|
http, server, location |
Activa la caché para conexiones a servidores de destino. Cuando el valor es mayor que 0, habilita conexiones keepalive para Fetch API.
El parámetro connections establece el número máximo de conexiones keepalive inactivas a servidores de destino que se conservan en la caché de cada proceso worker. Cuando se excede este número, se cierran las conexiones utilizadas menos recientemente.
Ejemplo:
location /fetch {
js_fetch_keepalive 32;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
js_content main.fetch_handler;
}
js_fetch_keepalive_requests#
| |
Predeterminado |
|
http, server, location |
Establece el número máximo de solicitudes que se pueden servir a través de una conexión keepalive con Fetch API. Después de realizar el número máximo de solicitudes, la conexión se cierra.
Cerrar conexiones periódicamente es necesario para liberar asignaciones de memoria por conexión. Por lo tanto, usar un número máximo de solicitudes demasiado alto podría resultar en un uso excesivo de memoria y no se recomienda.
js_fetch_keepalive_time#
| |
Predeterminado |
|
http, server, location |
Limita el tiempo máximo durante el cual las solicitudes se pueden procesar a través de una conexión keepalive con Fetch API. Después de alcanzar este tiempo, la conexión se cierra tras el procesamiento de la solicitud subsiguiente.
js_fetch_keepalive_timeout#
| |
Predeterminado |
|
http, server, location |
Establece un tiempo de espera durante el cual una conexión keepalive inactiva a un servidor de destino permanecerá abierta con Fetch API.
js_header_filter#
| |
Predeterminado | — |
location, if in location, limit_except |
Establece una función njs como filtro de cabecera de respuesta. La directiva permite cambiar campos de cabecera arbitrarios de una cabecera de respuesta.
Nota
Como el manejador js_header_filter devuelve su resultado inmediatamente, solo admite operaciones síncronas. Por lo tanto, no se admiten operaciones asíncronas como r.subrequest() o setTimeout().
js_import#
| |
Predeterminado | — |
http, server, location |
Importa un módulo que implementa manejadores de ubicación y variables en njs. El export_name se utiliza como un espacio de nombres para acceder a las funciones del módulo. Si no se especifica export_name, el nombre del módulo se utilizará como espacio de nombres.
js_import http.js;
Aquí, el nombre del módulo http se utiliza como espacio de nombres al acceder a las exportaciones. Si el módulo importado exporta foo(), se utiliza http.foo para referirse a ella.
Se pueden especificar varias directivas js_import.
js_path#
Establece una ruta adicional para los módulos njs.
js_periodic#
| |
Predeterminado | — |
location |
Especifica un manejador de contenido para ejecutarse a intervalos regulares. El manejador recibe un objeto de sesión como su primer argumento, también tiene acceso a objetos globales como ngx.
El parámetro opcional interval establece el intervalo entre dos ejecuciones consecutivas, por defecto, 5 segundos.
El parámetro opcional jitter establece el tiempo dentro del cual el manejador de contenido de la ubicación se retrasará aleatoriamente, por defecto, no hay retraso.
Por defecto, el js_handler se ejecuta en el proceso worker 0. El parámetro opcional worker_affinity permite especificar procesos worker particulares donde el manejador de contenido de ubicación debe ejecutarse. Cada conjunto de procesos worker se representa mediante una máscara de bits de procesos worker permitidos. La máscara all permite que el manejador se ejecute en todos los procesos worker.
Ejemplo:
example.conf:
location @periodics {
# para ejecutarse a intervalos de 1 minuto en el proceso worker 0
js_periodic main.handler interval=60s;
# para ejecutarse a intervalos de 1 minuto en todos los procesos worker
js_periodic main.handler interval=60s worker_affinity=all;
# para ejecutarse a intervalos de 1 minuto en los procesos worker 1 y 3
js_periodic main.handler interval=60s worker_affinity=0101;
resolver 10.0.0.1;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}
example.js:
async function handler(s) {
let reply = await ngx.fetch('https://example.com/');
let body = await reply.text();
ngx.log(ngx.INFO, body);
}
js_preload_object#
| |
Predeterminado | — |
http, server, location |
Precarga un objeto inmutable en el momento de la configuración. El name se utiliza como nombre de la variable global a través de la cual el objeto está disponible en el código njs. Si no se especifica name, se utilizará el nombre del archivo.
js_preload_object map.json;
Aquí, map se utiliza como nombre al acceder al objeto precargado.
Se pueden especificar varias directivas js_preload_object.
js_set#
| |
Predeterminado | — |
http, server, location |
Establece una función njs para la variable especificada. Se pueden referenciar funciones de módulos.
La función se llama cuando la variable se referencia por primera vez para una solicitud dada. El momento exacto depende de la fase en la que se referencia la variable. Esto se puede utilizar para realizar alguna lógica no relacionada con la evaluación de variables. Por ejemplo, si la variable solo se referencia en la directiva log_format, su manejador no se ejecutará hasta la fase de registro. Este manejador se puede utilizar para realizar alguna limpieza justo antes de que se libere la solicitud.
Desde njs 0.8.6, si se especifica un argumento opcional nocache, el manejador se llama cada vez que se hace referencia a él. Debido a las limitaciones actuales del módulo rewrite, cuando una variable nocache es referenciada por la directiva set, su manejador siempre debe devolver un valor de longitud fija.
Nota
Como el manejador js_set devuelve su resultado de forma inmediata, solo admite operaciones síncronas. Por lo tanto, no se admiten operaciones asíncronas como r.subrequest() o setTimeout().
js_var#
Declara una variable escribible. El valor puede contener texto, variables y su combinación. La variable no se sobrescribe después de una redirección, a diferencia de las variables creadas con la directiva set.
Argumento de Solicitud#
Cada manejador HTTP njs recibe un argumento, un objeto request.