<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../../dtd/module.dtd">
<module name="Модуль ngx_http_js_module"
link="/ru/docs/http/ngx_http_js_module.html"
lang="ru"
rev="59">
<section id="summary">
<para>
Модуль <literal>ngx_http_js_module</literal> позволяет задавать
обработчики location и переменных
на <link doc="../njs/index.xml">njs</link> —
подмножестве языка JavaScript.
</para>
<para>
Инструкция по сборке и установке доступны
<link doc="../njs/install.xml">здесь</link>.
</para>
</section>
<section id="example" name="Пример конфигурации">
<para>
Пример работает начиная с версии
<link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>.
<example>
http {
# начиная с 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;
}
# начиная с версии 0.7.0
location = /fetch {
js_content http.fetch;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}
# начиная с версии 0.7.0
location = /crypto {
add_header Hash $hash;
return 200;
}
}
}
</example>
</para>
<para>
Файл <path>http.js</path>:
<example>
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!");
}
// начиная с версии 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));
}
// начиная с версии 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};
</example>
</para>
</section>
<section id="directives" name="Директивы">
<directive name="js_body_filter">
<syntax><value>модуль.функция</value>
[<value>buffer_type</value>=<value>string</value> | <value>buffer</value>]</syntax>
<default/>
<context>location</context>
<context>if in location</context>
<context>limit_except</context>
<appeared-in>0.5.2</appeared-in>
<para>
Задаёт функцию njs в качестве фильтра тела ответа.
Функция фильтра вызывается для каждого блока данных тела ответа
со следующими аргументами:
<list type="tag">
<tag-name><literal>r</literal></tag-name>
<tag-desc>
объект <link doc="../njs/reference.xml" id="http">HTTP request</link>
</tag-desc>
<tag-name><literal>data</literal></tag-name>
<tag-desc>
входящий блок данных
может быть строкой или буфером
в зависимости от значения <literal>buffer_type</literal>,
по умолчанию является строкой.
Начиная с <link doc="../njs/changes.xml" id="njs0.8.5">0.8.5</link>,
по умолчанию
значение <literal>data</literal> неявно преобразуется в валидную строку UTF-8.
Для бинарных данных параметр <literal>buffer_type</literal>
необходимо установить в <literal>buffer</literal>.
</tag-desc>
<tag-name><literal>flags</literal></tag-name>
<tag-desc>
объект со следующими свойствами:
<list type="tag">
<tag-name><literal>last</literal></tag-name>
<tag-desc>
логическое значение, true, если данные являются последним буфером.
</tag-desc>
</list>
</tag-desc>
</list>
</para>
<para>
Функция фильтра может передавать свою модифицированную версию
входящего блока данных следующему фильтру тела ответа при помощи вызова
<link doc="../njs/reference.xml" id="r_sendbuffer"><literal>r.sendBuffer()</literal></link>.
Пример преобразования букв в нижний регистр в теле ответа:
<example>
function filter(r, data, flags) {
r.sendBuffer(data.toLowerCase(), flags);
}
</example>
Для отмены фильтра (блоки данных будут передаваться клиенту
без вызова <literal>js_body_filter</literal>),
можно использовать
<link doc="../njs/reference.xml" id="r_done"><literal>r.done()</literal></link>.
</para>
<para>
Если функция фильтра изменяет длину тела ответа, то
необходимо очистить заголовок ответа <header>Content-Length</header>
(если присутствует) в
<link id="js_header_filter"><literal>js_header_filter</literal></link>,
чтобы применить поблочное кодирование.
</para>
<para>
<note>
Так как обработчик <literal>js_body_filter</literal>
должен сразу возвращать результат,
то поддерживаются только синхронные операции,
Таким образом, асинхронные операции, например
<link doc="../njs/reference.xml" id="r_subrequest">r.subrequest()</link>
или
<link doc="../njs/reference.xml" id="settimeout">setTimeout()</link>,
не поддерживаются.
</note>
</para>
<para>
<note>
Директива может быть указана внутри
блока <link doc="../http/ngx_http_rewrite_module.xml" id="if">if</link>
начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>
</directive>
<directive name="js_access">
<syntax><value>модуль.функция</value></syntax>
<default/>
<context>location</context>
<context>if in location</context>
<context>limit_except</context>
<appeared-in>0.9.9</appeared-in>
<para>
Задаёт функцию njs в качестве обработчика
<link doc="../dev/development_guide.xml" id="http_phases">фазы доступа</link>.
Поддерживаются асинхронные операции, такие как
<link doc="../njs/reference.xml" id="r_subrequest">r.subrequest()</link>,
<link doc="../njs/reference.xml" id="ngx_fetch">ngx.fetch()</link>
и <link doc="../njs/reference.xml" id="settimeout">setTimeout()</link>.
</para>
<para>
Обработчик, завершившийся без вызова
<link doc="../njs/reference.xml" id="r_return"><literal>r.return()</literal></link>
или
<link doc="../njs/reference.xml" id="r_decline"><literal>r.decline()</literal></link>,
разрешает доступ.
Чтобы запретить доступ или отправить произвольный ответ
(например, перенаправление), обработчик может вызвать
<link doc="../njs/reference.xml" id="r_return"><literal>r.return()</literal></link>.
Чтобы обработчик не выражал мнения о доступе, передавая решение другим
проверкам доступа при использовании
<link doc="ngx_http_core_module.xml" id="satisfy"><literal>satisfy any</literal></link>,
обработчик может вызвать
<link doc="../njs/reference.xml" id="r_decline"><literal>r.decline()</literal></link>.
</para>
<para>
Например:
<example>
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};
</example>
</para>
</directive>
<directive name="js_content">
<syntax><value>модуль.функция</value></syntax>
<default/>
<context>location</context>
<context>if in location</context>
<context>limit_except</context>
<para>
Задаёт функцию njs в качестве обработчика содержимого location.
Начиная с версии <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>
можно ссылаться на функцию модуля.
</para>
<para>
<note>
Директива может быть указана внутри
блока <link doc="../http/ngx_http_rewrite_module.xml" id="if">if</link>
начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>
</directive>
<directive name="js_context_reuse">
<syntax><value>число</value></syntax>
<default>128</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.8.6</appeared-in>
<para>
Задаёт максимальное число контекстов JS для повторного использования
<link doc="../njs/engine.xml">движке QuickJS</link>.
Каждый контекст используется для одного запроса.
Завершённый контекст помещается в пул повторно используемых контекстов.
Если пул заполнен, контекст уничтожается.
</para>
</directive>
<directive name="js_engine">
<syntax><literal>njs</literal> | <literal>qjs</literal></syntax>
<default>njs</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.8.6</appeared-in>
<para>
Задаёт <link doc="../njs/engine.xml">движок JavaScript</link>
для использования в сценариях njs.
Параметр <literal>njs</literal> задаёт использование движка njs,
также используемого по умолчанию.
Параметр <literal>qjs</literal> задаёт использование движка QuickJS.
</para>
<para>
<note>
Движок <literal>njs</literal> объявлен устаревшим
начиная с <link doc="../njs/changes.xml" id="njs1.0.0">1.0.0</link>;
в новых конфигурациях следует использовать <literal>qjs</literal>
(<link doc="../njs/engine.xml" id="quickjs_engine">QuickJS</link>).
</note>
</para>
</directive>
<directive name="js_fetch_buffer_size">
<syntax><value>размер</value></syntax>
<default>16k</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.4</appeared-in>
<para>
Задаёт <value>размер</value> буфера, который будет использоваться
для чтения и записи для
<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
</directive>
<directive name="js_fetch_ciphers">
<syntax><value>шифры</value></syntax>
<default>HIGH:!aNULL:!MD5</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.0</appeared-in>
<para>
Описывает разрешённые шифры для HTTPS-запросов
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
Шифры задаются в формате, поддерживаемом библиотекой OpenSSL.
</para>
<para>
Полный список можно посмотреть с помощью команды
“<command>openssl ciphers</command>”.
</para>
</directive>
<directive name="js_fetch_max_response_buffer_size">
<syntax><value>размер</value></syntax>
<default>1m</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.4</appeared-in>
<para>
Задаёт максимальный <value>размер</value> ответа, полученного
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
</directive>
<directive name="js_fetch_protocols">
<syntax>
[<literal>TLSv1</literal>]
[<literal>TLSv1.1</literal>]
[<literal>TLSv1.2</literal>]
[<literal>TLSv1.3</literal>]</syntax>
<default>TLSv1 TLSv1.1 TLSv1.2</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.0</appeared-in>
<para>
Разрешает указанные протоколы для HTTPS-запросов
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
</directive>
<directive name="js_fetch_timeout">
<syntax><value>время</value></syntax>
<default>60s</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.4</appeared-in>
<para>
Задаёт таймаут при чтении и записи
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
Таймаут устанавливается не на всю передачу ответа,
а только между двумя операциями чтения.
Если по истечении этого времени данные не передавались, соединение закрывается.
</para>
</directive>
<directive name="js_fetch_trusted_certificate">
<syntax><value>файл</value></syntax>
<default/>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.0</appeared-in>
<para>
Задаёт <value>файл</value> с доверенными сертификатами CA в формате PEM,
используемыми при
<link doc="../njs/reference.xml" id="fetch_verify">проверке</link>
HTTPS-сертификата
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
</directive>
<directive name="js_fetch_verify">
<syntax><literal>on</literal> | <literal>off</literal></syntax>
<default>on</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.4</appeared-in>
<para>
Разрешает или запрещает проверку сертификата HTTPS-сервера
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
</directive>
<directive name="js_fetch_verify_depth">
<syntax><value>число</value></syntax>
<default>100</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.0</appeared-in>
<para>
Устанавливает глубину проверки в цепочке HTTPS-сертификатов
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
</directive>
<directive name="js_fetch_proxy">
<syntax><value>url</value></syntax>
<default/>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.9.4</appeared-in>
<para>
Задаёт URL прямого прокси-сервера
при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
<value>url</value> поддерживает только схему HTTP
и может содержать необязательные учётные данные пользователя
в формате <literal>http://[user:password@]host:port</literal>
для базовой аутентификации.
Поддерживает как HTTP, так и HTTPS соединения с серверами назначения.
Если <value>url</value> пустой, маршрутизация через прокси отключается.
Значение параметра может содержать переменные.
</para>
<para>
Пример:
<example>
location /fetch {
js_fetch_proxy http://user:[email protected]:3128;
js_content main.fetch_handler;
}
</example>
</para>
</directive>
<directive name="js_fetch_keepalive">
<syntax><value>соединения</value></syntax>
<default>0</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.9.2</appeared-in>
<para>
Активирует кэш для соединений с серверами назначения.
Если значение больше <literal>0</literal>,
включает keepalive-соединения для
<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
<para>
Параметр <value>соединения</value> задаёт максимальное количество
неактивных keepalive-соединений с серверами назначения,
которые сохраняются в кэше каждого рабочего процесса.
Если это количество превышено, наименее недавно использованные соединения закрываются.
</para>
<para>
В HTTP кэш ведётся отдельно для каждой итоговой конфигурации location.
Значение, заданное на уровне <literal>http</literal> или
<literal>server</literal>, наследуется location, но каждый location
использует свой кэш.
Закэшированные соединения повторно используются для запросов с тем же
протоколом, именем узла и портом.
</para>
<para>
При включении keepalive предполагается, что серверы назначения отправляют
корректные HTTP-ответы.
</para>
<para>
Пример:
<example>
location /fetch {
js_fetch_keepalive 32;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
js_content main.fetch_handler;
}
</example>
</para>
</directive>
<directive name="js_fetch_keepalive_requests">
<syntax><value>число</value></syntax>
<default>1000</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.9.2</appeared-in>
<para>
Задаёт максимальное количество запросов, которые могут быть обслужены
через одно keepalive-соединение при помощи
<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
После выполнения максимального количества запросов соединение закрывается.
</para>
<para>
Периодическое закрытие соединений необходимо для освобождения
выделенной под соединение памяти.
Поэтому использование слишком большого максимального количества запросов
может привести к чрезмерному потреблению памяти и не рекомендуется.
</para>
</directive>
<directive name="js_fetch_keepalive_time">
<syntax><value>время</value></syntax>
<default>1h</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.9.2</appeared-in>
<para>
Ограничивает максимальное время, в течение которого запросы могут обрабатываться
через одно keepalive-соединение при помощи
<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
По истечении этого времени соединение закрывается после обработки очередного запроса.
</para>
</directive>
<directive name="js_fetch_keepalive_timeout">
<syntax><value>время</value></syntax>
<default>60s</default>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.9.2</appeared-in>
<para>
Задаёт таймаут, в течение которого неактивное keepalive-соединение
с сервером назначения остается открытым при помощи
<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>
</directive>
<directive name="js_header_filter">
<syntax><value>модуль.функция</value></syntax>
<default/>
<context>location</context>
<context>if in location</context>
<context>limit_except</context>
<appeared-in>0.5.1</appeared-in>
<para>
Задаёт функцию njs в качестве фильтра заголовка ответа.
Директива позволяет менять произвольные поля заголовка ответа.
</para>
<para>
<note>
Так как обработчик <literal>js_header_filter</literal>
должен сразу возвращать результат,
то поддерживаются только синхронные операции,
Таким образом, асинхронные операции, например
<link doc="../njs/reference.xml" id="r_subrequest">r.subrequest()</link>
или
<link doc="../njs/reference.xml" id="settimeout">setTimeout()</link>,
не поддерживаются.
</note>
</para>
<para>
<note>
Директива может быть указана внутри
блока <link doc="../http/ngx_http_rewrite_module.xml" id="if">if</link>
начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>
</directive>
<directive name="js_import">
<syntax><value>модуль.js</value> |
<value>имя_экспорта from модуль.js</value></syntax>
<default/>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.4.0</appeared-in>
<para>
Импортирует модуль, позволяющий задавать обработчики location и переменных
на njs.
<literal>Имя_экспорта</literal> является пространством имён
при доступе к функциям модуля.
Если <literal>имя_экспорта</literal> не задано,
то пространством имён будет являться имя модуля.
<example>
js_import http.js;
</example>
В примере при доступе к экспорту в качестве
пространства имён используется имя модуля <literal>http</literal>.
Если импортируемый модуль экспортирует <literal>foo()</literal>,
то для доступа используется <literal>http.foo</literal>.
</para>
<para>
Директив <literal>js_import</literal> может быть несколько.
</para>
<para>
<note>
Директива может быть указана
на уровне <literal>server</literal> и <literal>location</literal>
начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>
</directive>
<directive name="js_include">
<syntax><value>файл</value></syntax>
<default/>
<context>http</context>
<para>
Задаёт файл, позволяющий задавать обработчики location и переменных на njs:
<example>
nginx.conf:
js_include http.js;
location /version {
js_content version;
}
http.js:
function version(r) {
r.return(200, njs.version);
}
</example>
</para>
<para>
Директива устарела в версии
<link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>
и была удалена в версии
<link doc="../njs/changes.xml" id="njs0.7.1">0.7.1</link>.
Вместо неё следует использовать директиву <link id="js_import"/>.
</para>
</directive>
<directive name="js_load_http_native_module">
<syntax><value>путь</value> [<literal>as</literal> <value>имя</value>]</syntax>
<default/>
<context>main</context>
<appeared-in>0.9.5</appeared-in>
<para>
Загружает <link doc="../njs/native_modules.xml">нативный модуль</link>
(разделяемую библиотеку) для использования в HTTP JavaScript-коде.
Директива работает только с движком
<link doc="../njs/engine.xml" id="quickjs_engine">QuickJS</link>
и недоступна при использовании встроенного движка njs.
</para>
<para>
Параметр <value>путь</value>
задаёт абсолютный путь к файлу разделяемой библиотеки.
Необязательный параметр <literal>as</literal> <value>имя</value>
задаёт псевдоним для импорта модуля в JavaScript-коде.
Если не указан, модуль можно импортировать по имени файла.
</para>
<para>
Пример:
<example>
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;
# ... остальная конфигурация http
}
</example>
В JavaScript-коде:
<example>
// Импорт по имени файла
import * as mylib from 'mylib.so';
// Импорт по псевдониму
import * as myalias from 'myalias';
// Использование экспортируемых функций
let result = mylib.add(5, 10);
</example>
</para>
<para>
<note>
В целях безопасности директива может использоваться только
в контексте <literal>main</literal>.
Нативные модули работают с полными привилегиями процесса,
необходимо использовать абсолютные пути и проводить проверку кода.
</note>
</para>
</directive>
<directive name="js_path">
<syntax>
<value>путь</value></syntax>
<default/>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.3.0</appeared-in>
<para>
Задаёт дополнительный путь для модулей njs.
</para>
<para>
<note>
Директива может быть указана
на уровне <literal>server</literal> и <literal>location</literal>
начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>
</directive>
<directive name="js_periodic">
<syntax><value>модуль.функция</value>
[<literal>interval</literal>=<value>время</value>]
[<literal>jitter</literal>=<value>число</value>]
[<literal>worker_affinity</literal>=<value>маска</value>]</syntax>
<default/>
<context>location</context>
<appeared-in>0.8.1</appeared-in>
<para>
Задаёт периодичность запуска обработчика содержимого.
В качестве первого аргумента обработчик получает
<link doc="../njs/reference.xml" id="periodic_session">объект сессии</link>,
также у обработчика есть доступ к глобальным объектам таким как
<link doc="../njs/reference.xml" id="ngx">ngx</link>.
</para>
<para>
Необязательный параметр <literal>interval</literal>
задаёт интервал между двумя последовательными запусками,
по умолчанию 5 секунд.
</para>
<para>
Необязательный параметр <literal>jitter</literal>
задаёт время, в пределах которого
случайным образом задерживается каждый запуск,
по умолчанию задержки нет.
</para>
<para>
По умолчанию <literal>js_handler</literal> выполняется для рабочего процесса 0.
Необязательный параметр <literal>worker_affinity</literal>
позволяет указать рабочий процесс,
для которого будет выполняться обработчик содержимого location.
Рабочие процессы задаются битовой маской разрешённых к использованию рабочих
процессов.
Маска <literal>all</literal> позволяет обработчику выполняться
для всех рабочих процессов.
</para>
<para>
Пример:
<example>
example.conf:
location @periodics {
# интервал выполнения 1 минута для рабочего процесса 0
js_periodic main.handler interval=60s;
# интервал выполнения 1 минута для всех рабочих процессов
js_periodic main.handler interval=60s worker_affinity=all;
# интервал выполнения 1 минута для рабочих процессов 1 и 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);
}
</example>
</para>
</directive>
<directive name="js_preload_object">
<syntax><value>имя.json</value> |
<value>имя</value> from <value>файл.json</value></syntax>
<default/>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.8</appeared-in>
<para>
Предварительно загружает
<link doc="../njs/preload_objects.xml">неизменяемый объект</link>
во время конфигурации.
<literal>Имя</literal> используется в качестве имени глобальной переменной,
через которую объект доступен в коде njs.
Если <literal>имя</literal> не указано,
то будет использоваться имя файла.
<example>
js_preload_object map.json;
</example>
В примере <literal>map</literal> используется в качестве имени
во время доступа к предварительно загруженному объекту.
</para>
<para>
Директив <literal>js_preload_object</literal> может быть несколько.
</para>
</directive>
<directive name="js_set">
<syntax>
<value>$переменная</value>
<value>модуль.функция</value>
[<literal>nocache</literal>]</syntax>
<default/>
<context>http</context>
<context>server</context>
<context>location</context>
<para>
Задаёт <literal>функцию</literal> njs
для указанной <literal>переменной</literal>.
Начиная с <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>
можно ссылаться на функцию модуля.
</para>
<para>
Функция вызывается в момент
первого обращения к переменной для данного запроса.
Точный момент вызова функции зависит от
<link doc="../dev/development_guide.xml" id="http_phases">фазы</link>,
в которой происходит обращение к переменной.
Это можно использовать для реализации дополнительной логики,
не относящейся к вычислению переменной.
Например, если переменная указана
в директиве <link doc="ngx_http_log_module.xml" id="log_format"/>,
то её обработчик не будет выполняться до фазы записи в лог.
Этот обработчик также может использоваться для выполнения процедур
непосредственно перед освобождением запроса.
</para>
<para>
Начиная с <link doc="../njs/changes.xml" id="njs0.8.6">0.8.6</link>,
если указан необязательный параметр <literal>nocache</literal>, то
обработчик выполняется каждый раз при обращении к переменной.
Из-за ограничения модуля <link doc="ngx_http_rewrite_module.xml">rewrite</link>
при обращении к <literal>nocache</literal>-переменной при помощи
директивы <link doc="ngx_http_rewrite_module.xml" id="set">set</link>,
обработчик должен возвращать значение фиксированной длины.
</para>
<para>
<note>
Так как обработчик <literal>js_set</literal>
должен сразу возвращать результат,
то поддерживаются только синхронные операции,
Таким образом, асинхронные операции, например
<link doc="../njs/reference.xml" id="r_subrequest">r.subrequest()</link>
или
<link doc="../njs/reference.xml" id="settimeout">setTimeout()</link>,
не поддерживаются.
</note>
</para>
<para>
<note>
Директива может быть указана
на уровне <literal>server</literal> и <literal>location</literal>
начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>
</directive>
<directive name="js_shared_dict_zone">
<syntax>
<literal>zone</literal>=<value>имя</value>:<value>размер</value>
[<literal>timeout</literal>=<value>время</value>]
[<literal>type</literal>=<literal>строка</literal>|<literal>число</literal>]
[<literal>evict</literal>]</syntax>
<default/>
<context>http</context>
<appeared-in>0.8.0</appeared-in>
<para>
Задаёт <value>имя</value> и <value>размер</value> зоны разделяемой памяти,
в которой хранится
<link doc="../njs/reference.xml" id="dict">словарь</link> ключей и значений,
разделяемый между рабочими процессами.
</para>
<para>
По умолчанию в качестве ключа и значения используется строка.
Необязательный параметр <literal>type</literal>
позволяет изменить тип значения на число.
</para>
<para>
Необязательный параметр <literal>timeout</literal> задаёт время в миллисекундах,
по завершении которого все записи в словаре удаляются из зоны.
Если для части записей требуется другое время удаления,
его можно задать при помощи аргумента <literal>timeout</literal>
методов
<link doc="../njs/reference.xml" id="dict_add">add</link>,
<link doc="../njs/reference.xml" id="dict_incr">incr</link> и
<link doc="../njs/reference.xml" id="dict_set">set</link>
(<link doc="../njs/changes.xml" id="njs0.8.5">0.8.5</link>).
</para>
<para>
Необязательный параметр <literal>evict</literal> удаляет самую старую
пару ключ-значение при переполнении зоны.
</para>
<para>
Пример:
<example>
example.conf:
# Создаётся словарь размером 1Мб со строковыми значениями,
# пары ключ-значение удаляются при отсутствии активности в течение 60 секунд:
js_shared_dict_zone zone=foo:1M timeout=60s;
# Создаётся словарь размером 512Кб со строковыми значениями,
# удаляется самая старая пара ключ-значение при переполнении зоны:
js_shared_dict_zone zone=bar:512K timeout=30s evict;
# Создаётся постоянный словарь размером 32Кб с числовыми значениями:
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));
}
</example>
</para>
</directive>
<directive name="js_var">
<syntax><value>$переменная</value> [<value>значение</value>]</syntax>
<default/>
<context>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.5.3</appeared-in>
<para>
Объявляет
<link doc="../njs/reference.xml" id="r_variables">перезаписываемую</link>
переменную.
В качестве значения можно использовать текст, переменные и их комбинации.
Переменная не перезаписывается после перенаправления,
в отличие от переменных, созданных при помощи
директивы <link doc="ngx_http_rewrite_module.xml" id="set"/>.
</para>
<para>
<note>
Директива может быть указана
на уровне <literal>server</literal> и <literal>location</literal>
начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>
</directive>
</section>
<section id="arguments" name="Аргумент запроса">
<para>
Каждый HTTP-обработчик njs получает один аргумент,
<link doc="../njs/reference.xml" id="http">объект</link> запроса.
</para>
</section>
</module>