Spec-Zone.ru › nginx

Модуль ngx_http_js_module

  • Пример конфигурации
  • Директивы
  • js_body_filter
  • js_access
  • js_content
  • js_context_reuse
  • js_engine
  • js_fetch_buffer_size
  • js_fetch_ciphers
  • js_fetch_max_response_buffer_size
  • js_fetch_protocols
  • js_fetch_timeout
  • js_fetch_trusted_certificate
  • js_fetch_verify
  • js_fetch_verify_depth
  • js_fetch_proxy
  • js_fetch_keepalive
  • js_fetch_keepalive_requests
  • js_fetch_keepalive_time
  • js_fetch_keepalive_timeout
  • js_header_filter
  • js_import
  • js_include
  • js_load_http_native_module
  • js_path
  • js_periodic
  • js_preload_object
  • js_set
  • js_shared_dict_zone
  • js_var
  • Аргумент запроса

Модуль ngx_http_js_module используется для реализации обработчиков расположений и переменных в njs — подмножестве языка JavaScript.

Инструкции по загрузке и установке доступны здесь.

Пример конфигурации

Пример работает начиная с версии 0.4.0.

http {
    # since 0.9.1
    js_engine qjs;

    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;
        }

        # since 0.7.0
        location = /fetch {
            js_content                   http.fetch;
            js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
        }

        # since 0.7.0
        location = /crypto {
            add_header Hash $hash;
            return     200;
        }
    }
}

Файл 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!");
}

// since 0.7.0
async function fetch(r) {
    let results = await Promise.all([ngx.fetch('https://nginx.org/'),
                                     ngx.fetch('https://nginx.org/en/')]);

    r.return(200, JSON.stringify(results, undefined, 4));
}

// since 0.7.0
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};

Директивы

Синтаксис: js_body_filter module.function [buffer_type=string | buffer];
Значение по умолчанию: —
Контекст: location, if in location, limit_except

Директива появилась в версии 0.5.2.

Назначает функцию njs фильтром тела ответа. Функция фильтра вызывается для каждого блока данных тела ответа со следующими аргументами:

r
объект HTTP-запроса
data
входящий блок данных; в зависимости от значения buffer_type это может быть строка или Buffer, по умолчанию — строка. Начиная с версии 0.8.5, значение data по умолчанию неявно преобразуется в допустимую строку UTF-8. Для двоичных данных следует задать значение buffer_type равным buffer.
flags
объект со следующими свойствами:
last
логическое значение: true, если это последний буфер данных.

Функция фильтра может передать следующему фильтру тела собственную изменённую версию входящего блока данных, вызвав r.sendBuffer(). Например, чтобы преобразовать все строчные буквы в теле ответа:

function filter(r, data, flags) {
    r.sendBuffer(data.toLowerCase(), flags);
}

Если функция фильтра изменяет длину тела ответа, заголовок ответа «Content-Length» (если он присутствует) следует очистить в js_header_filter, чтобы включить передачу с кодированием chunked:

example.conf:
 location /foo {
     # proxy_pass http://localhost:8080;

    js_header_filter main.clear_content_length;
    js_body_filter   main.filter;
 }

example.js:
 function clear_content_length(r) {
     delete r.headersOut['Content-Length'];
 }

Чтобы прекратить фильтрацию и передать блоки данных клиенту, не вызывая js_body_filter, можно использовать r.done(). Например, чтобы добавить данные в начало тела ответа:

function prepend(r, data, flags) {
    r.sendBuffer("XXX");
    r.sendBuffer(data, flags);
    r.done();
}
Поскольку обработчик js_body_filter немедленно возвращает результат, он поддерживает только синхронные операции. Поэтому асинхронные операции, такие как r.subrequest() или setTimeout(), не поддерживаются.
Директиву можно указывать внутри блока if начиная с версии 0.7.7.
Синтаксис: js_access module.function;
Значение по умолчанию: —
Контекст: location, if in location, limit_except

Директива появилась в версии 0.9.9.

Назначает функцию njs обработчиком в фазе доступа. Поддерживаются асинхронные операции, такие как r.subrequest(), ngx.fetch() и setTimeout().

Обработчик, который возвращает управление, не вызывая r.return() или r.decline(), разрешает доступ. Чтобы запретить доступ или отправить собственный ответ (например, перенаправление), обработчик может вызвать r.return(). Чтобы обработчик не выносил решения и передал его другим проверяющим доступ согласно директиве satisfy any, он может вызвать r.decline().

Например:

example.conf:
 location /protected/ {
     js_access  main.auth;
     proxy_pass http://upstream;
 }

example.js:
 async function auth(r) {
     let reply = await ngx.fetch('http://authsvc/check', {
         headers: {Authorization: r.headersIn.Authorization}
     });

     if (reply.status != 200) {
         r.return(401);
         return;
     }
 }

 export default {auth};
Синтаксис: js_content module.function;
Значение по умолчанию: —
Контекст: location, if in location, limit_except

Назначает функцию njs обработчиком содержимого расположения. Начиная с версии 0.4.0, можно ссылаться на функцию модуля.

Директиву можно указывать внутри блока if начиная с версии 0.7.7.
Синтаксис: js_context_reuse number;
Значение по умолчанию: js_context_reuse 128;
Контекст: http, server, location

Директива появилась в версии 0.8.6.

Задаёт максимальное число контекстов JS, которые можно повторно использовать в движке QuickJS. Каждый контекст используется для одного запроса. Завершивший работу контекст помещается в пул повторно используемых контекстов. Если пул заполнен, контекст уничтожается.

Синтаксис: js_engine njs | qjs;
Значение по умолчанию: js_engine njs;
Контекст: http, server, location

Директива появилась в версии 0.8.6.

Задаёт движок JavaScript, который будет использоваться для скриптов njs. Параметр njs задаёт движок njs, используемый также по умолчанию. Параметр qjs задаёт движок QuickJS.

Движок njs объявлен устаревшим начиная с версии 1.0.0; в новых конфигурациях следует использовать движок qjs (QuickJS).
Синтаксис: js_fetch_buffer_size size;
Значение по умолчанию: js_fetch_buffer_size 16k;
Контекст: http, server, location

Директива появилась в версии 0.7.4.

Задаёт size буфера, используемого для чтения и записи с помощью Fetch API.

Синтаксис: js_fetch_ciphers ciphers;
Значение по умолчанию: js_fetch_ciphers HIGH:!aNULL:!MD5;
Контекст: http, server, location

Директива появилась в версии 0.7.0.

Задаёт разрешённые шифры для HTTPS-запросов с помощью Fetch API. Шифры задаются в формате, поддерживаемом библиотекой OpenSSL.

Полный список можно просмотреть с помощью команды «openssl ciphers».

Синтаксис: js_fetch_max_response_buffer_size size;
Значение по умолчанию: js_fetch_max_response_buffer_size 1m;
Контекст: http, server, location

Директива появилась в версии 0.7.4.

Задаёт максимальный size ответа, полученного с помощью Fetch API.

Синтаксис: js_fetch_protocols [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
Значение по умолчанию: js_fetch_protocols TLSv1 TLSv1.1 TLSv1.2;
Контекст: http, server, location

Директива появилась в версии 0.7.0.

Разрешает указанные протоколы для HTTPS-запросов с помощью Fetch API.

Синтаксис: js_fetch_timeout time;
Значение по умолчанию: js_fetch_timeout 60s;
Контекст: http, server, location

Директива появилась в версии 0.7.4.

Задаёт тайм-аут чтения и записи для Fetch API. Тайм-аут применяется только между двумя последовательными операциями чтения/записи, а не ко всему ответу. Если за это время данные не передаются, соединение закрывается.

Синтаксис: js_fetch_trusted_certificate file;
Значение по умолчанию: —
Контекст: http, server, location

Директива появилась в версии 0.7.0.

Задаёт file с доверенными сертификатами CA в формате PEM, используемый для проверки сертификата HTTPS с помощью Fetch API.

Синтаксис: js_fetch_verify on | off;
Значение по умолчанию: js_fetch_verify on;
Контекст: http, server, location

Директива появилась в версии 0.7.4.

Включает или отключает проверку сертификата HTTPS-сервера с помощью Fetch API.

Синтаксис: js_fetch_verify_depth number;
Значение по умолчанию: js_fetch_verify_depth 100;
Контекст: http, server, location

Директива появилась в версии 0.7.0.

Задаёт глубину проверки цепочки сертификатов HTTPS-сервера с помощью Fetch API.

Синтаксис: js_fetch_proxy url;
Значение по умолчанию: —
Контекст: http, server, location

Директива появилась в версии 0.9.4.

Настраивает URL прямого прокси-сервера для Fetch API. Параметр url поддерживает только схему HTTP и может содержать необязательные учётные данные пользователя в формате http://[user:password@]host:port для базовой аутентификации. Поддерживаются подключения по HTTP и HTTPS к серверам назначения. Если url пуст, маршрутизация через прокси отключена. Значение параметра может содержать переменные.

Пример:

location /fetch {
    js_fetch_proxy http://user:pass@proxy.example.com:3128;
    js_content main.fetch_handler;
}
Синтаксис: js_fetch_keepalive connections;
Значение по умолчанию: js_fetch_keepalive 0;
Контекст: http, server, location

Директива появилась в версии 0.9.2.

Включает кэширование подключений к серверам назначения. Если значение больше 0, для Fetch API включаются постоянные соединения.

Параметр connections задаёт максимальное число простаивающих постоянных соединений с серверами назначения, сохраняемых в кэше каждого рабочего процесса. При превышении этого числа закрываются соединения, которые использовались дольше всего назад.

Пример:

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 number;
Значение по умолчанию: js_fetch_keepalive_requests 1000;
Контекст: http, server, location

Директива появилась в версии 0.9.2.

Задаёт максимальное число запросов, которые можно обработать через одно постоянное соединение с помощью Fetch API. После обработки максимального числа запросов соединение закрывается.

Периодически закрывать соединения необходимо для освобождения выделенной для них памяти. Поэтому слишком большое максимальное число запросов может привести к чрезмерному использованию памяти и не рекомендуется.

Синтаксис: js_fetch_keepalive_time time;
Значение по умолчанию: js_fetch_keepalive_time 1h;
Контекст: http, server, location

Директива появилась в версии 0.9.2.

Ограничивает максимальное время, в течение которого запросы могут обрабатываться через одно постоянное соединение с помощью Fetch API. По истечении этого времени соединение закрывается после обработки следующего запроса.

Синтаксис: js_fetch_keepalive_timeout time;
Значение по умолчанию: js_fetch_keepalive_timeout 60s;
Контекст: http, server, location

Директива появилась в версии 0.9.2.

Задаёт тайм-аут, в течение которого простаивающее постоянное соединение с сервером назначения остаётся открытым для Fetch API.

Синтаксис: js_header_filter module.function;
Значение по умолчанию: —
Контекст: location, if in location, limit_except

Директива появилась в версии 0.5.1.

Назначает функцию njs фильтром заголовка ответа. Директива позволяет изменять произвольные поля заголовка ответа.

Поскольку обработчик js_header_filter немедленно возвращает результат, он поддерживает только синхронные операции. Поэтому асинхронные операции, такие как r.subrequest() или setTimeout(), не поддерживаются.
Директиву можно указывать внутри блока if начиная с версии 0.7.7.
Синтаксис: js_import module.js | export_name from module.js;
Значение по умолчанию: —
Контекст: http, server, location

Директива появилась в версии 0.4.0.

Импортирует модуль, реализующий обработчики расположений и переменных в njs. Параметр export_name используется как пространство имён для доступа к функциям модуля. Если export_name не задан, в качестве пространства имён используется имя модуля.

js_import http.js;

Здесь имя модуля http используется как пространство имён при доступе к экспортируемым объектам. Если импортированный модуль экспортирует foo(), для обращения к нему используется http.foo.

Можно указать несколько директив js_import.

Если js_import указана внутри location, импортированные модули доступны только в том случае, если ранее в запросе не выполнялся код JavaScript. Для каждого запроса создаётся одна виртуальная машина при первом обращении к переменной js_set или первом вызове обработчика js_content, js_header_filter, js_body_filter или js_access. Виртуальная машина копируется из области конфигурации, активной в этот момент, и все последующие вызовы JavaScript в рамках запроса используют её повторно. Поэтому, если к любому из перечисленных выше обработчиков обращаются до того, как запрос сопоставлен с конечным расположением, например из директивы set уровня server, виртуальная машина привязывается к набору импортов внешней области, и модули, импортированные в соответствующем location, будут недоступны. Чтобы этого избежать, объявляйте такие импорты в общей родительской области.

Директиву можно указывать на уровне server и location начиная с версии 0.7.7.
Синтаксис: js_include file;
Значение по умолчанию: —
Контекст: http

Указывает файл, реализующий обработчики расположений и переменных в njs:

nginx.conf:
js_include http.js;
location   /version {
    js_content version;
}

http.js:
function version(r) {
    r.return(200, njs.version);
}

Директива устарела в версии 0.4.0 и удалена в версии 0.7.1. Вместо неё следует использовать директиву js_import.

Синтаксис: js_load_http_native_module path [as name];
Значение по умолчанию: —
Контекст: main

Директива появилась в версии 0.9.5.

Загружает нативный модуль (разделяемую библиотеку) для использования в коде JavaScript HTTP. Директива доступна только в QuickJS и не работает при использовании встроенного движка JavaScript njs.

Параметр path задаёт абсолютный путь к файлу разделяемой библиотеки. Необязательный параметр as name задаёт псевдоним для импорта модуля в коде JavaScript. Если он не указан, модуль можно импортировать по имени файла.

Пример:

js_load_http_native_module /path/to/mylib.so;
js_load_http_native_module /path/to/other.so as myalias;

http {
    js_import main.js;
    # ... rest of http configuration
}

В коде JavaScript:

// Import by filename
import * as mylib from 'mylib.so';

// Import by alias
import * as myalias from 'myalias';

// Use exported functions
let result = mylib.add(5, 10);
По соображениям безопасности эту директиву разрешено использовать только в контексте конфигурации main. Нативные модули выполняются с полными правами процесса; используйте абсолютные пути и тщательно проверяйте код.
Синтаксис: js_path path;
Значение по умолчанию: —
Контекст: http, server, location

Директива появилась в версии 0.3.0.

Задаёт дополнительный путь для модулей njs.

Директиву можно указывать на уровне server и location начиная с версии 0.7.7.
Синтаксис: js_periodic module.function [interval=time] [jitter=number] [worker_affinity=mask];
Значение по умолчанию: —
Контекст: location

Директива появилась в версии 0.8.1.

Задаёт обработчик содержимого, который запускается с регулярным интервалом. Первым аргументом обработчик получает объект сеанса; ему также доступны глобальные объекты, такие как ngx.

Необязательный параметр interval задаёт интервал между последовательными запусками; по умолчанию — 5 секунд.

Необязательный параметр jitter задаёт промежуток времени, в пределах которого запуск обработчика содержимого расположения будет случайным образом отложен; по умолчанию задержки нет.

По умолчанию js_handler выполняется в рабочем процессе 0. Необязательный параметр worker_affinity позволяет указать конкретные рабочие процессы, в которых должен выполняться обработчик содержимого расположения. Каждый набор рабочих процессов представлен битовой маской разрешённых рабочих процессов. Маска all позволяет выполнять обработчик во всех рабочих процессах.

Пример:

example.conf:

location @periodics {
    # to be run at 1 minute intervals in worker process 0
    js_periodic main.handler interval=60s;

    # to be run at 1 minute intervals in all worker processes
    js_periodic main.handler interval=60s worker_affinity=all;

    # to be run at 1 minute intervals in worker processes 1 and 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://nginx.org/en/docs/njs/');
    let body = await reply.text();

    ngx.log(ngx.INFO, body);
}
Синтаксис: js_preload_object name.json | name from file.json;
Значение по умолчанию: —
Контекст: http, server, location

Директива появилась в версии 0.7.8.

Предварительно загружает неизменяемый объект на этапе настройки. Параметр name используется как имя глобальной переменной, через которую объект доступен в коде njs. Если name не задан, вместо него используется имя файла.

js_preload_object map.json;

Здесь map используется как имя для доступа к предварительно загруженному объекту.

Можно указать несколько директив js_preload_object.

Синтаксис: js_set $variable module.function [nocache];
Значение по умолчанию: —
Контекст: http, server, location

Назначает function njs указанной variable. Начиная с версии 0.4.0, можно ссылаться на функцию модуля.

Функция вызывается при первом обращении к переменной в рамках данного запроса. Точный момент зависит от фазы, в которой используется переменная. Это можно использовать для выполнения логики, не связанной с вычислением значения переменной. Например, если переменная используется только в директиве log_format, её обработчик будет выполнен только в фазе логирования. Этот обработчик можно использовать для очистки непосредственно перед освобождением запроса.

Начиная с версии 0.8.6, если указан необязательный аргумент nocache, обработчик вызывается при каждом обращении к переменной. Из-за текущих ограничений модуля rewrite, при использовании переменной nocache в директиве set её обработчик должен всегда возвращать значение фиксированной длины.

Поскольку обработчик js_set немедленно возвращает результат, он поддерживает только синхронные операции. Поэтому асинхронные операции, такие как r.subrequest() или setTimeout(), не поддерживаются.
Директиву можно указывать на уровне server и location начиная с версии 0.7.7.
Синтаксис: js_shared_dict_zone zone=name:size [timeout=time] [type=string|number] [evict] [state=file];
Значение по умолчанию: —
Контекст: http

Директива появилась в версии 0.8.0.

Задаёт name и size зоны общей памяти, в которой хранится общий для рабочих процессов словарь «ключ-значение» .

По умолчанию в общем словаре для ключей и значений используются строки. Необязательный параметр type позволяет изменить тип значения на число.

Необязательный параметр timeout задаёт время в миллисекундах, по истечении которого все записи общего словаря удаляются из зоны. Для записей, которые нужно удалять через другое время, его можно задать аргументом timeout методов add, incr и set (0.8.5).

Необязательный параметр evict удаляет самую старую пару «ключ-значение», если пространство зоны исчерпано.

Необязательный параметр state задаёт file, который сохраняет состояние общего словаря в формате JSON и обеспечивает его сохранение после перезапуска nginx (0.9.1).

Пример:

example.conf:
    # Creates a 1Mb dictionary with string values,
    # removes key-value pairs after 60 seconds of inactivity:
    js_shared_dict_zone zone=foo:1M timeout=60s;

    # Creates a 512Kb dictionary with string values,
    # forcibly removes oldest key-value pairs when the zone is exhausted:
    js_shared_dict_zone zone=bar:512K timeout=30s evict;

    # Creates a 32Kb permanent dictionary with number values:
    js_shared_dict_zone zone=num:32k type=number;

    # Creates a 1Mb dictionary with string values and persistent state:
    js_shared_dict_zone zone=persistent:1M state=/tmp/dict.json;

example.js:
    function get(r) {
        r.return(200, ngx.shared.foo.get(r.args.key));
    }

    function set(r) {
        r.return(200, ngx.shared.foo.set(r.args.key, r.args.value));
    }

    function del(r) {
        r.return(200, ngx.shared.bar.delete(r.args.key));
    }

    function increment(r) {
        r.return(200, ngx.shared.num.incr(r.args.key, 2));
    }
Синтаксис: js_var $variable [value];
Значение по умолчанию: —
Контекст: http, server, location

Директива появилась в версии 0.5.3.

Объявляет доступную для записи переменную. Значение может содержать текст, переменные или их сочетание. В отличие от переменных, созданных директивой set, эта переменная не перезаписывается после перенаправления.

Директиву можно указывать на уровне server и location начиная с версии 0.7.7.

Аргумент запроса

Каждый обработчик HTTP njs получает один аргумент — объект запроса.

© 2002-2021 Igor Sysoev
© 2011-2026 Nginx, Inc.
Licensed under the BSD License.
https://nginx.org/en/docs/http/ngx_http_js_module.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API