Модуль ngx_http_js_module
- Пример конфигурации
- Директивы
- js_body_filter
- js_content
- 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_header_filter
- js_import
- js_include
- 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 {
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 function | module.function
[buffer_type=string | buffer]; |
|---|---|
| По умолчанию: | — |
| Контекст: | location, if in location, limit_except |
Эта директива появилась в версии 0.5.2.
Устанавливает функцию njs в качестве фильтра тела ответа. Функция-фильтр вызывается для каждого фрагмента данных тела ответа со следующими аргументами:
r- объект запроса HTTP
data- входящий фрагмент данных, может быть строкой или буфером в зависимости от значения
buffer_type, по умолчанию — строка. flags- объект со следующими свойствами:
last- булево значение, true, если данные — последний буфер.
Функция-фильтр может передать свою изменённую версию входного фрагмента данных следующему фильтру тела, вызвав r.sendBuffer(). Например, для преобразования всех строчных букв в теле ответа:
function filter(r, data, flags) {
r.sendBuffer(data.toLowerCase(), flags);
}
Чтобы остановить фильтрацию (следующие фрагменты данных будут переданы клиенту без вызова js_body_filter), можно использовать r.done().
Если функция-фильтр изменяет длину тела ответа, то необходимо очистить заголовок ответа «Content-Length» (если есть) в js_header_filter, чтобы обеспечить кодирование передачи блоками.
Поскольку обработчик js_body_filter возвращает свой результат немедленно, он поддерживает только синхронные операции. Таким образом, асинхронные операции, такие как r.subrequest() или setTimeout(), не поддерживаются. Директива может быть указана внутри блока if с версии 0.7.7.
| Синтаксис: | js_content function | module.function; |
|---|---|
| По умолчанию: | — |
| Контекст: | location, if in location, limit_except |
Устанавливает функцию njs как обработчик содержимого расположения. С версии 0.4.0, можно ссылаться на функцию модуля.
Директива может быть указана внутри блока if с версии 0.7.7.
| Синтаксис: | js_fetch_buffer_size size; |
|---|---|
| По умолчанию: | js_fetch_buffer_size 16k; |
| Контекст: | http, server, location |
Эта директива появилась в версии 0.7.4.
Устанавливает размер size буфера, используемого для чтения и записи с помощью API Fetch.
| Синтаксис: | js_fetch_ciphers ciphers; |
|---|---|
| По умолчанию: | js_fetch_ciphers HIGH:!aNULL:!MD5; |
| Контекст: | http, server, location |
Эта директива появилась в версии 0.7.0.
Указывает включенные шифры для HTTPS-запросов с помощью API Fetch. Шифры задаются в формате, понятном для библиотеки OpenSSL.
Полный список можно посмотреть, используя команду “openssl ciphers”.
| Синтаксис: | js_fetch_max_response_buffer_size size; |
|---|---|
| По умолчанию: | js_fetch_max_response_buffer_size 1m; |
| Контекст: | http, server, location |
Эта директива появилась в версии 0.7.4.
Устанавливает максимальный size полученного ответа с помощью API Fetch.
| Синтаксис: | 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-запросов с помощью API Fetch.
| Синтаксис: | js_fetch_timeout time; |
|---|---|
| По умолчанию: | js_fetch_timeout 60s; |
| Контекст: | http, server, location |
Эта директива появилась в версии 0.7.4.
Определяет таймаут для чтения и записи для API Fetch. Таймаут устанавливается только между двумя последовательными операциями чтения/записи, а не для всего ответа. Если данные не передаются в течение этого времени, соединение закрывается.
| Синтаксис: | js_fetch_trusted_certificate file; |
|---|---|
| По умолчанию: | — |
| Контекст: | http, server, location |
Эта директива появилась в версии 0.7.0.
Указывает файл file с доверенными сертификатами CA в формате PEM, используемый для проверки сертификата HTTPS с помощью API Fetch.
| Синтаксис: | js_fetch_verify on | off; |
|---|---|
| По умолчанию: | js_fetch_verify on; |
| Контекст: | http, server, location |
Эта директива появилась в версии 0.7.4.
Включает или отключает проверку сертификата HTTPS сервера с помощью API Fetch.
| Синтаксис: | js_fetch_verify_depth number; |
|---|---|
| По умолчанию: | js_fetch_verify_depth 100; |
| Контекст: | http, server, location |
Эта директива появилась в версии 0.7.0.
Устанавливает глубину проверки в цепочке сертификатов HTTPS сервера с помощью API Fetch.
| Синтаксис: | js_header_filter function | 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 |
Импортирует модуль, реализующий обработчики местоположений и переменных в njs. export_name используется в качестве пространства имён для доступа к функциям модуля. Если export_name не указан, имя модуля будет использоваться как пространство имён.
js_import http.js;
Здесь имя модуля http используется как пространство имён при доступе к экспортам. Если импортированный модуль экспортирует foo(), для ссылки на него используется http.foo.
Можно указать несколько директив js_import.
Директива может быть указана на уровне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_path
path; |
|---|---|
| Значение по умолчанию: | — |
| Контекст: | http, server, location |
Данная директива появилась в версии 0.3.0.
Устанавливает дополнительный путь для модулей njs.
Директива может быть указана на уровнеserverиlocationначиная с версии 0.7.7.
| Синтаксис: | js_periodic function |
module.function
[interval=time]
[jitter=number]
[worker_affinity=mask]; |
|---|---|
| Значение по умолчанию: | — |
| Контекст: | location |
Данная директива появилась в версии 0.8.1.
Указывает обработчик содержимого, который будет выполняться через регулярные интервалы. Обработчик получает объект сессии session в качестве первого аргумента, а также имеет доступ к глобальным объектам, таким как 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.
Предварительно загружает неизменяемый объект immutable во время конфигурации. name используется как имя глобальной переменной, через которую объект доступен в коде njs. Если name не указан, используется имя файла вместо него.
js_preload_object map.json;
Здесь map используется как имя при доступе к предварительно загруженному объекту.
Можно указать несколько директив js_preload_object.
| Синтаксис: | js_set
$variable function |
module.function; |
|---|---|
| Значение по умолчанию: | — |
| Контекст: | http, server, location |
Устанавливает njs function для указанного variable. Начиная с версии 0.4.0, можно ссылаться на функцию модуля.
Функция вызывается при первой ссылке на переменную для данного запроса. Точное время зависит от фазы фазы, в которой переменная была использована. Это можно использовать для выполнения некоторой логики, не связанной с оценкой переменной. Например, если переменная используется только в директиве log_format, её обработчик не будет выполнен до фазы логирования. Этот обработчик можно использовать для очистки перед освобождением запроса.
Поскольку обработчик js_set возвращает результат немедленно, он поддерживает только синхронные операции. Таким образом, асинхронные операции, такие как r.subrequest() или setTimeout(), не поддерживаются. Директива может быть указана на уровнеserverиlocationначиная с версии 0.7.7.
Устанавливает name и size зоны общей памяти, которая хранит словарь ключ-значение dictionary, общие для рабочих процессов.
По умолчанию, общий словарь использует строку в качестве ключа и значения. Необязательный параметр type позволяет переопределить тип значения на число.
Необязательный параметр timeout устанавливает время в миллисекундах, после которого все записи общего словаря удаляются из зоны. Если некоторые записи требуют другого времени удаления, это можно установить с аргументом timeout методов add, incr и set (0.8.5).
Необязательный параметр evict удаляет самую старую пару ключ-значение, когда хранилище зоны заполнено.
Пример:
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;
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 получает один аргумент — объект запроса http.
© 2002-2021 Igor Sysoev
© 2011-2024 Nginx, Inc.
Licensed under the BSD License.
https://nginx.org/en/docs/http/ngx_http_js_module.html