Path: blob/main/xml/ru/docs/stream/ngx_stream_js_module.xml
1 views
<?xml version="1.0"?>12<!--3Copyright (C) Nginx, Inc.4-->56<!DOCTYPE module SYSTEM "../../../../dtd/module.dtd">78<module name="Модуль ngx_stream_js_module"9link="/ru/docs/stream/ngx_stream_js_module.html"10lang="ru"11rev="55">1213<section id="summary">1415<para>16Модуль <literal>ngx_stream_js_module</literal> позволяет задавать17обработчики на <link doc="../njs/index.xml">njs</link> —18подмножестве языка JavaScript.19</para>2021<para>22Инструкция по сборке и установке доступны23<link doc="../njs/install.xml">здесь</link>.24</para>2526</section>272829<section id="example" name="Пример конфигурации">3031<para>32Пример работает начиная с версии33<link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>.34<example>35stream {36# начиная с 0.9.137js_engine qjs;3839js_import stream.js;4041js_set $bar stream.bar;42js_set $req_line stream.req_line;4344server {45listen 12345;4647js_preread stream.preread;48return $req_line;49}5051server {52listen 12346;5354js_access stream.access;55proxy_pass 127.0.0.1:8000;56js_filter stream.header_inject;57}58}5960http {61server {62listen 8000;63location / {64return 200 $http_foo\n;65}66}67}68</example>69</para>7071<para>72Файл <path>stream.js</path>:73<example>74var line = '';7576function bar(s) {77var v = s.variables;78s.log("hello from bar() handler!");79return "bar-var" + v.remote_port + "; pid=" + v.pid;80}8182function preread(s) {83s.on('upload', function (data, flags) {84var n = data.indexOf('\n');85if (n != -1) {86line = data.substr(0, n);87s.done();88}89});90}9192function req_line(s) {93return line;94}9596// Чтение строки HTTP-запроса.97// Получение байт в 'req' до того как98// будет прочитана строка запроса.99// Добавление HTTP-заголовка в запрос клиента100101var my_header = 'Foo: foo';102function header_inject(s) {103var req = '';104s.on('upload', function(data, flags) {105req += data;106var n = req.search('\n');107if (n != -1) {108var rest = req.substr(n + 1);109req = req.substr(0, n + 1);110s.send(req + my_header + '\r\n' + rest, flags);111s.off('upload');112}113});114}115116function access(s) {117if (s.remoteAddress.match('^192.*')) {118s.deny();119return;120}121122s.allow();123}124125export default {bar, preread, req_line, header_inject, access};126</example>127</para>128129</section>130131132<section id="directives" name="Директивы">133134<directive name="js_access">135<syntax><value>модуль.функция</value></syntax>136<default/>137<context>stream</context>138<context>server</context>139140<para>141Задаёт функцию njs, которая будет вызываться в142<link doc="stream_processing.xml" id="access_phase">access</link>-фазе.143Начиная с <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>144можно ссылаться на функцию модуля.145</para>146147<para>148Функция вызывается однократно при первом достижении сессией149<link doc="stream_processing.xml" id="access_phase">access</link>-фазы.150Функция вызывается со следующими аргументами:151152<list type="tag">153<tag-name><literal>s</literal></tag-name>154<tag-desc>155объект <link doc="../njs/reference.xml" id="stream">stream-сессии</link>156</tag-desc>157158</list>159</para>160161<para>162В этой фазе может происходить инициализация,163также при помощи метода164<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>165может регистрироваться вызов166для каждого входящего блока данных пока не будет вызван один из методов:167<link doc="../njs/reference.xml" id="s_done"><literal>s.done()</literal></link>168<link doc="../njs/reference.xml" id="s_decline"><literal>s.decline()</literal></link>,169<link doc="../njs/reference.xml" id="s_allow"><literal>s.allow()</literal></link>.170При вызове любого из этих методов обработка сессии171переходит на <link doc="stream_processing.xml">следующую фазу</link>172и все текущие вызовы173<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>174сбрасываются.175</para>176177</directive>178179180<directive name="js_context_reuse">181<syntax><value>число</value></syntax>182<default>128</default>183<context>stream</context>184<context>server</context>185<appeared-in>0.8.6</appeared-in>186187<para>188Задаёт максимальное число контекстов JS для повторного использования189<link doc="../njs/engine.xml">движке QuickJS</link>.190Каждый контекст используется для одной stream-сессии.191Завершённый контекст помещается в пул повторно используемых контекстов.192Если пул заполнен, контекст уничтожается.193</para>194195</directive>196197198<directive name="js_engine">199<syntax><literal>njs</literal> | <literal>qjs</literal></syntax>200<default>njs</default>201<context>stream</context>202<context>server</context>203<appeared-in>0.8.6</appeared-in>204205<para>206Задаёт <link doc="../njs/engine.xml">движок JavaScript</link>207для использования в сценариях njs.208Параметр <literal>njs</literal> задаёт использование движка njs,209также используемого по умолчанию.210Параметр <literal>qjs</literal> задаёт использование движка QuickJS.211</para>212213<para>214<note>215Движок <literal>njs</literal> объявлен устаревшим216начиная с <link doc="../njs/changes.xml" id="njs1.0.0">1.0.0</link>;217в новых конфигурациях следует использовать <literal>qjs</literal>218(<link doc="../njs/engine.xml" id="quickjs_engine">QuickJS</link>).219</note>220</para>221222</directive>223224225<directive name="js_fetch_buffer_size">226<syntax><value>размер</value></syntax>227<default>16k</default>228<context>stream</context>229<context>server</context>230<appeared-in>0.7.4</appeared-in>231232<para>233Задаёт <value>размер</value> буфера, который будет использоваться234для чтения и записи для235<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.236</para>237238</directive>239240241<directive name="js_fetch_ciphers">242<syntax><value>шифры</value></syntax>243<default>HIGH:!aNULL:!MD5</default>244<context>stream</context>245<context>server</context>246<appeared-in>0.7.0</appeared-in>247248<para>249Описывает разрешённые шифры для HTTPS-соединений250при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.251Шифры задаются в формате, поддерживаемом библиотекой OpenSSL.252</para>253254<para>255Полный список можно посмотреть с помощью команды256“<command>openssl ciphers</command>”.257</para>258259</directive>260261262<directive name="js_fetch_max_response_buffer_size">263<syntax><value>размер</value></syntax>264<default>1m</default>265<context>stream</context>266<context>server</context>267<appeared-in>0.7.4</appeared-in>268269<para>270Задаёт максимальный <value>размер</value> ответа, полученного271при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.272</para>273274</directive>275276277<directive name="js_fetch_protocols">278<syntax>279[<literal>TLSv1</literal>]280[<literal>TLSv1.1</literal>]281[<literal>TLSv1.2</literal>]282[<literal>TLSv1.3</literal>]</syntax>283<default>TLSv1 TLSv1.1 TLSv1.2</default>284<context>stream</context>285<context>server</context>286<appeared-in>0.7.0</appeared-in>287288<para>289Разрешает указанные протоколы для HTTPS-соединений290при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.291</para>292293</directive>294295296<directive name="js_fetch_timeout">297<syntax><value>время</value></syntax>298<default>60s</default>299<context>stream</context>300<context>server</context>301<appeared-in>0.7.4</appeared-in>302303<para>304Задаёт таймаут при чтении и записи305при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.306Таймаут устанавливается не на всю передачу ответа,307а только между двумя операциями чтения.308Если по истечении этого времени данные не передавались, соединение закрывается.309</para>310311</directive>312313314<directive name="js_fetch_trusted_certificate">315<syntax><value>файл</value></syntax>316<default/>317<context>stream</context>318<context>server</context>319<appeared-in>0.7.0</appeared-in>320321<para>322Задаёт <value>файл</value> с доверенными сертификатами CA в формате PEM,323используемыми при324<link doc="../njs/reference.xml" id="fetch_verify">проверке</link>325HTTPS-сертификата326при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.327</para>328329</directive>330331332<directive name="js_fetch_verify">333<syntax><literal>on</literal> | <literal>off</literal></syntax>334<default>on</default>335<context>stream</context>336<context>server</context>337<appeared-in>0.7.4</appeared-in>338339<para>340Разрешает или запрещает проверку сертификата HTTPS-сервера341при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.342</para>343344</directive>345346347<directive name="js_fetch_verify_depth">348<syntax><value>число</value></syntax>349<default>100</default>350<context>stream</context>351<context>server</context>352<appeared-in>0.7.0</appeared-in>353354<para>355Устанавливает глубину проверки в цепочке HTTPS-сертификатов356при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.357</para>358359</directive>360361362<directive name="js_fetch_proxy">363<syntax><value>url</value></syntax>364<default/>365<context>stream</context>366<context>server</context>367<appeared-in>0.9.4</appeared-in>368369<para>370Задаёт URL прямого прокси-сервера371при помощи <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.372<value>url</value> поддерживает только схему HTTP373и может содержать необязательные учётные данные пользователя374в формате <literal>http://[user:password@]host:port</literal>375для базовой аутентификации.376Поддерживает как HTTP, так и HTTPS соединения с серверами назначения.377Если <value>url</value> пустой, маршрутизация через прокси отключается.378Значение параметра может содержать переменные.379</para>380381<para>382Пример:383<example>384server {385listen 12345;386js_fetch_proxy http://user:[email protected]:3128;387js_preread main.fetch_handler;388}389</example>390</para>391392</directive>393394395<directive name="js_fetch_keepalive">396<syntax><value>соединения</value></syntax>397<default>0</default>398<context>stream</context>399<context>server</context>400<appeared-in>0.9.2</appeared-in>401402<para>403Активирует кэш для соединений с серверами назначения.404Если значение больше <literal>0</literal>,405включает keepalive-соединения для406<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.407</para>408409<para>410Параметр <value>соединения</value> задаёт максимальное количество411неактивных keepalive-соединений с серверами назначения,412которые сохраняются в кэше каждого рабочего процесса.413Если это количество превышено, наименее недавно использованные соединения закрываются.414</para>415416<para>417В Stream кэш ведётся отдельно для каждой конфигурации server.418Значение, заданное на уровне <literal>stream</literal>, наследуется419серверами, но каждый server использует свой кэш.420Закэшированные соединения повторно используются для запросов с тем же421протоколом, именем узла и портом.422</para>423424<para>425При включении keepalive предполагается, что серверы назначения отправляют426корректные HTTP-ответы.427</para>428429<para>430Пример:431<example>432server {433listen 12345;434js_fetch_keepalive 32;435js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;436js_preread main.fetch_handler;437}438</example>439</para>440441</directive>442443444<directive name="js_fetch_keepalive_requests">445<syntax><value>число</value></syntax>446<default>1000</default>447<context>stream</context>448<context>server</context>449<appeared-in>0.9.2</appeared-in>450451<para>452Задаёт максимальное количество запросов, которые могут быть обслужены453через одно keepalive-соединение при помощи454<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.455После выполнения максимального количества запросов соединение закрывается.456</para>457458<para>459Периодическое закрытие соединений необходимо для освобождения460выделенной под соединение памяти.461Поэтому использование слишком большого максимального количества запросов462может привести к чрезмерному потреблению памяти и не рекомендуется.463</para>464465</directive>466467468<directive name="js_fetch_keepalive_time">469<syntax><value>время</value></syntax>470<default>1h</default>471<context>stream</context>472<context>server</context>473<appeared-in>0.9.2</appeared-in>474475<para>476Ограничивает максимальное время, в течение которого запросы могут обрабатываться477через одно keepalive-соединение при помощи478<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.479По истечении этого времени соединение закрывается после обработки очередного запроса.480</para>481482</directive>483484485<directive name="js_fetch_keepalive_timeout">486<syntax><value>время</value></syntax>487<default>60s</default>488<context>stream</context>489<context>server</context>490<appeared-in>0.9.2</appeared-in>491492<para>493Задаёт таймаут, в течение которого неактивное keepalive-соединение494с сервером назначения остается открытым при помощи495<link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.496</para>497498</directive>499500501<directive name="js_filter">502<syntax><value>модуль.функция</value></syntax>503<default/>504<context>stream</context>505<context>server</context>506507<para>508Задаёт фильтр данных.509Начиная с <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>510можно ссылаться на функцию модуля.511Функция фильтра вызывается однократно при первом достижении сессией512<link doc="stream_processing.xml" id="content_phase">content</link>-фазы.513</para>514515<para>516Функция фильтра вызывается со следующими аргументами:517<list type="tag">518<tag-name><literal>s</literal></tag-name>519<tag-desc>520объект <link doc="../njs/reference.xml" id="stream">stream-сессии</link>521</tag-desc>522523</list>524</para>525526<para>527В этой фазе может происходить инициализация,528также при помощи метода529<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>530может регистрироваться вызов531для каждого входящего блока данных.532Для отмены регистрации вызова и отмены фильтра533можно использовать метод534<link doc="../njs/reference.xml" id="s_off"><literal>s.off()</literal></link>.535</para>536537<para>538<note>539Так как обработчик <literal>js_filter</literal>540должен сразу возвращать результат,541то поддерживаются только синхронные операции.542Таким образом, асинхронные операции, например543<link doc="../njs/reference.xml" id="ngx_fetch"><literal>ngx.fetch()</literal></link>544или545<link doc="../njs/reference.xml" id="settimeout"><literal>setTimeout()</literal></link>,546не поддерживаются.547</note>548</para>549550</directive>551552553<directive name="js_import">554<syntax><value>модуль.js</value> |555<value>имя_экспорта from модуль.js</value></syntax>556<default/>557<context>stream</context>558<context>server</context>559<appeared-in>0.4.0</appeared-in>560561<para>562Импортирует модуль, позволяющий задавать обработчики location и переменных563на njs.564<literal>Имя_экспорта</literal> является пространством имён565при доступе к функциям модуля.566Если <literal>имя_экспорта</literal> не задано,567то пространством имён будет являться имя модуля.568<example>569js_import stream.js;570</example>571В примере при доступе к экспорту в качестве572пространства имён используется имя модуля <literal>stream</literal>.573Если импортируемый модуль экспортирует <literal>foo()</literal>,574то для доступа используется <literal>stream.foo</literal>.575</para>576577<para>578Директив <literal>js_import</literal> может быть несколько.579</para>580581<para>582<note>583Директива может быть указана584на уровне <literal>server</literal>585начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.586</note>587</para>588589</directive>590591592<directive name="js_include">593<syntax><value>файл</value></syntax>594<default/>595<context>stream</context>596597<para>598Задаёт файл, который позволяет задавать обработчики server и переменных на njs:599<example>600nginx.conf:601js_include stream.js;602js_set $js_addr address;603server {604listen 127.0.0.1:12345;605return $js_addr;606}607608stream.js:609function address(s) {610return s.remoteAddress;611}612</example>613</para>614615<para>616Директива устарела в версии617<link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>618и была удалена в версии619<link doc="../njs/changes.xml" id="njs0.7.1">0.7.1</link>.620Вместо неё следует использовать директиву <link id="js_import"/>.621</para>622623</directive>624625626<directive name="js_preload_object">627<syntax><value>имя.json</value> |628<value>имя</value> from <value>файл.json</value></syntax>629<default/>630<context>stream</context>631<context>server</context>632<appeared-in>0.7.8</appeared-in>633634<para>635Предварительно загружает636<link doc="../njs/preload_objects.xml">неизменяемый объект</link>637во время конфигурации.638<literal>Имя</literal> используется в качестве имени глобальной переменной,639через которую объект доступен в коде njs.640Если <literal>имя</literal> не указано,641то будет использоваться имя файла.642<example>643js_preload_object map.json;644</example>645В примере <literal>map</literal> используется в качестве имени646во время доступа к предварительно загруженному объекту.647</para>648649<para>650Директив <literal>js_preload_object</literal> может быть несколько.651</para>652653</directive>654655656<directive name="js_preread">657<syntax><value>модуль.функция</value></syntax>658<default/>659<context>stream</context>660<context>server</context>661662<para>663Задаёт функцию njs, которая будет вызываться в664<link doc="stream_processing.xml" id="preread_phase">preread</link>-фазе.665Начиная с <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>666можно ссылаться на функцию модуля.667</para>668669<para>670Функция вызывается однократно при первом достижении сессией671<link doc="stream_processing.xml" id="preread_phase">preread</link>-фазы.672Функция вызывается со следующими аргументами:673674<list type="tag">675<tag-name><literal>s</literal></tag-name>676<tag-desc>677объект <link doc="../njs/reference.xml" id="stream">stream-сессии</link>678</tag-desc>679680</list>681</para>682683<para>684В этой фазе может происходить инициализация,685также при помощи метода686<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>687может регистрироваться вызов688для каждого входящего блока данных пока не будет вызван один из методов:689<link doc="../njs/reference.xml" id="s_done"><literal>s.done()</literal></link>690<link doc="../njs/reference.xml" id="s_decline"><literal>s.decline()</literal></link>,691<link doc="../njs/reference.xml" id="s_allow"><literal>s.allow()</literal></link>.692При вызове любого из этих методов обработка сессии693переходит на <link doc="stream_processing.xml">следующую фазу</link>694и все текущие вызовы695<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>696сбрасываются.697</para>698699<para>700<note>701Так как обработчик <literal>js_preread</literal>702должен сразу возвращать результат,703то поддерживаются только синхронные операции.704Таким образом, асинхронные операции, например705<link doc="../njs/reference.xml" id="ngx_fetch"><literal>ngx.fetch()</literal></link>706или707<link doc="../njs/reference.xml" id="settimeout"><literal>setTimeout()</literal></link>,708не поддерживаются.709Тем не менее асинхронные операции поддерживаются в вызовах710<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>711в712<link doc="stream_processing.xml" id="preread_phase">preread</link>-фазе.713Подробнее см.714<link url="https://github.com/nginx/njs-examples#authorizing-connections-using-ngx-fetch-as-auth-request-stream-auth-request">пример</link>.715</note>716</para>717718</directive>719720721<directive name="js_load_stream_native_module">722<syntax><value>путь</value> [<literal>as</literal> <value>имя</value>]</syntax>723<default/>724<context>main</context>725<appeared-in>0.9.5</appeared-in>726727<para>728Загружает <link doc="../njs/native_modules.xml">нативный модуль</link>729(разделяемую библиотеку) для использования в Stream JavaScript-коде.730Директива работает только с движком731<link doc="../njs/engine.xml" id="quickjs_engine">QuickJS</link>732и недоступна при использовании встроенного движка njs.733</para>734735<para>736Параметр <value>путь</value>737задаёт абсолютный путь к файлу разделяемой библиотеки.738Необязательный параметр <literal>as</literal> <value>имя</value>739задаёт псевдоним для импорта модуля в JavaScript-коде.740Если не указан, модуль можно импортировать по имени файла.741</para>742743<para>744Пример:745<example>746js_load_stream_native_module /path/to/mylib.so;747js_load_stream_native_module /path/to/other.so as myalias;748749stream {750js_import main.js;751# ... остальная конфигурация stream752}753</example>754В JavaScript-коде:755<example>756// Импорт по имени файла757import * as mylib from 'mylib.so';758759// Импорт по псевдониму760import * as myalias from 'myalias';761762// Использование экспортируемых функций763let result = mylib.add(5, 10);764</example>765</para>766767<para>768<note>769В целях безопасности директива может использоваться только770в контексте <literal>main</literal>.771Нативные модули работают с полными привилегиями процесса,772необходимо использовать абсолютные пути и проводить проверку кода.773</note>774</para>775776</directive>777778779<directive name="js_path">780<syntax>781<value>путь</value></syntax>782<default/>783<context>stream</context>784<context>server</context>785<appeared-in>0.3.0</appeared-in>786787<para>788Задаёт дополнительный путь для модулей njs.789</para>790791<para>792<note>793Директива может быть указана794на уровне <literal>server</literal>795начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.796</note>797</para>798799</directive>800801802<directive name="js_periodic">803<syntax><value>модуль.функция</value>804[<literal>interval</literal>=<value>время</value>]805[<literal>jitter</literal>=<value>число</value>]806[<literal>worker_affinity</literal>=<value>маска</value>]</syntax>807<default/>808<context>server</context>809<appeared-in>0.8.1</appeared-in>810811<para>812Задаёт периодичность запуска обработчика содержимого.813В качестве первого аргумента обработчик получает814<link doc="../njs/reference.xml" id="periodic_session">объект сессии</link>,815также у обработчика есть доступ к глобальным объектам таким как816<link doc="../njs/reference.xml" id="ngx">ngx</link>.817</para>818819<para>820Необязательный параметр <literal>interval</literal>821задаёт интервал между двумя последовательными запусками,822по умолчанию 5 секунд.823</para>824825<para>826Необязательный параметр <literal>jitter</literal>827задаёт время, в пределах которого828случайным образом задерживается каждый запуск,829по умолчанию задержки нет.830</para>831832<para>833По умолчанию <literal>js_handler</literal> выполняется для рабочего процесса 0.834Необязательный параметр <literal>worker_affinity</literal>835позволяет указать рабочий процесс,836для которого будет выполняться обработчик содержимого location.837Рабочие процессы задаются битовой маской разрешённых к использованию рабочих838процессов.839Маска <literal>all</literal> позволяет обработчику выполняться840для всех рабочих процессов.841</para>842843<para>844Пример:845<example>846example.conf:847848location @periodics {849# интервал выполнения 1 минута для рабочего процесса 0850js_periodic main.handler interval=60s;851852# интервал выполнения 1 минута для всех рабочих процессов853js_periodic main.handler interval=60s worker_affinity=all;854855# интервал выполнения 1 минута для рабочих процессов 1 и 3856js_periodic main.handler interval=60s worker_affinity=0101;857858resolver 10.0.0.1;859js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;860}861862example.js:863864async function handler(s) {865let reply = await ngx.fetch('https://nginx.org/en/docs/njs/');866let body = await reply.text();867868ngx.log(ngx.INFO, body);869}870</example>871</para>872873</directive>874875876<directive name="js_set">877<syntax>878<value>$переменная</value>879<value>модуль.функция</value>880[<literal>nocache</literal>]</syntax>881<default/>882<context>stream</context>883<context>server</context>884885<para>886Задаёт <literal>функцию</literal> njs887для указанной <literal>переменной</literal>.888Начиная с <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>889можно ссылаться на функцию модуля.890</para>891892<para>893Функция вызывается в момент894первого обращения к переменной для данного запроса.895Точный момент вызова функции зависит от896<link doc="stream_processing.xml">фазы</link>,897в которой происходит обращение к переменной.898Это можно использовать для реализации дополнительной логики,899не относящейся к вычислению переменной.900Например, если переменная указана901в директиве <link doc="ngx_stream_log_module.xml" id="log_format"/>,902то её обработчик не будет выполняться до фазы записи в лог.903Этот обработчик также может использоваться для выполнения процедур904непосредственно перед освобождением запроса.905</para>906907<para>908Начиная с <link doc="../njs/changes.xml" id="njs0.8.6">0.8.6</link>,909если указан необязательный параметр <literal>nocache</literal>, то910обработчик выполняется каждый раз при обращении к переменной.911Из-за ограничения модуля <link doc="ngx_stream_rewrite_module.xml">rewrite</link>912при обращении к <literal>nocache</literal>-переменной при помощи913директивы <link doc="ngx_stream_rewrite_module.xml" id="set">set</link>,914обработчик должен возвращать значение фиксированной длины.915</para>916917<para>918<note>919Так как обработчик <literal>js_set</literal>920должен сразу возвращать результат,921то поддерживаются только синхронные операции.922Таким образом, асинхронные операции, например923<link doc="../njs/reference.xml" id="ngx_fetch"><literal>ngx.fetch()</literal></link>924или925<link doc="../njs/reference.xml" id="settimeout"><literal>setTimeout()</literal></link>,926не поддерживаются.927</note>928</para>929930<para>931<note>932Директива может быть указана933на уровне <literal>server</literal>934начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.935</note>936</para>937938</directive>939940941<directive name="js_shared_dict_zone">942<syntax>943<literal>zone</literal>=<value>имя</value>:<value>размер</value>944[<literal>timeout</literal>=<value>время</value>]945[<literal>type</literal>=<literal>строка</literal>|<literal>число</literal>]946[<literal>evict</literal>]</syntax>947<default/>948<context>stream</context>949<appeared-in>0.8.0</appeared-in>950951<para>952Задаёт <value>имя</value> и <value>размер</value> зоны разделяемой памяти,953в которой хранится954<link doc="../njs/reference.xml" id="dict">словарь</link> ключей и значений,955разделяемый между рабочими процессами.956</para>957958<para>959По умолчанию в качестве ключа и значения используется строка.960Необязательный параметр <literal>type</literal>961позволяет изменить тип значения на число.962</para>963964<para>965Необязательный параметр <literal>timeout</literal> задаёт время в миллисекундах,966по завершении которого все записи в словаре удаляются из зоны.967Если для части записей требуется другое время удаления,968его можно задать при помощи аргумента <literal>timeout</literal>969методов970<link doc="../njs/reference.xml" id="dict_add">add</link>,971<link doc="../njs/reference.xml" id="dict_incr">incr</link> и972<link doc="../njs/reference.xml" id="dict_set">set</link>973(<link doc="../njs/changes.xml" id="njs0.8.5">0.8.5</link>).974</para>975976<para>977Необязательный параметр <literal>evict</literal> удаляет самую старую978пару ключ-значение при переполнении зоны.979</para>980981<para>982Пример:983<example>984example.conf:985# Создаётся словарь размером 1Мб со строковыми значениями,986# пары ключ-значение удаляются при отсутствии активности в течение 60 секунд:987js_shared_dict_zone zone=foo:1M timeout=60s;988989# Создаётся словарь размером 512Кб со строковыми значениями,990# удаляется самая старая пара ключ-значение при переполнении зоны:991js_shared_dict_zone zone=bar:512K timeout=30s evict;992993# Создаётся постоянный словарь размером 32Кб с числовыми значениями:994js_shared_dict_zone zone=num:32k type=number;995996example.js:997function get(r) {998r.return(200, ngx.shared.foo.get(r.args.key));999}10001001function set(r) {1002r.return(200, ngx.shared.foo.set(r.args.key, r.args.value));1003}10041005function del(r) {1006r.return(200, ngx.shared.bar.delete(r.args.key));1007}10081009function increment(r) {1010r.return(200, ngx.shared.num.incr(r.args.key, 2));1011}1012</example>1013</para>10141015</directive>101610171018<directive name="js_var">1019<syntax><value>$переменная</value> [<value>значение</value>]</syntax>1020<default/>1021<context>stream</context>1022<context>server</context>1023<appeared-in>0.5.3</appeared-in>10241025<para>1026Объявляет1027<link doc="../njs/reference.xml" id="r_variables">перезаписываемую</link>1028переменную.1029В качестве значения можно использовать текст, переменные и их комбинации.1030</para>10311032<para>1033<note>1034Директива может быть указана1035на уровне <literal>server</literal>1036начиная с <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.1037</note>1038</para>10391040</directive>10411042</section>104310441045<section id="properties" name="Свойства объекта сессии">10461047<para>1048Каждый stream-обработчик njs получает один аргумент,1049<link doc="../njs/reference.xml" id="stream">объект</link> stream-сессии.1050</para>10511052</section>10531054</module>105510561057