モジュール ngx_http_js_module
ngx_http_js_module
モジュールは、JavaScript言語のサブセットであるnjsで、ロケーションハンドラーと変数ハンドラーを実装するために使用されます。
ダウンロードとインストールの手順はこちらにあります。
設定例
この例は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.dokyumento.jp/'), ngx.fetch('https://nginx.dokyumento.jp/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 |
---|---|
デフォルト | — |
コンテキスト |
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); }
フィルタリングを停止する場合(以降のデータチャンクはjs_body_filter
を呼び出さずにクライアントに渡されます)、r.done()
を使用できます。
フィルター関数がレスポンスボディの長さを変更する場合、チャンク転送エンコーディングを強制するために、js_header_filter
で「Content-Length」レスポンスヘッダー(存在する場合)をクリアする必要があります。
js_body_filter
ハンドラーは結果をすぐに返すため、同期操作のみをサポートします。したがって、r.subrequest()やsetTimeout()などの非同期操作はサポートされていません。
このディレクティブは、ifブロック内で0.7.7以降に指定できます。
構文 |
js_content |
---|---|
デフォルト | — |
コンテキスト |
location , if in location , limit_except |
njs関数をロケーションコンテンツハンドラーとして設定します。0.4.0以降、モジュール関数を参照できます。
このディレクティブは、ifブロック内で0.7.7以降に指定できます。
構文 |
js_context_reuse |
---|---|
デフォルト |
js_context_reuse 128; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.8.6で登場しました。
QuickJSエンジンで再利用されるJSコンテキストの最大数を設定します。各コンテキストは、単一のリクエストに使用されます。完了したコンテキストは、再利用可能なコンテキストのプールに入れられます。プールがいっぱいの場合は、コンテキストが破棄されます。
構文 |
js_engine |
---|---|
デフォルト |
js_engine njs; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.8.6で登場しました。
njsスクリプトに使用されるJavaScriptエンジンを設定します。njs
パラメータはnjsエンジンを設定します。これはデフォルトでも使用されます。qjs
パラメータはQuickJSエンジンを設定します。
構文 |
js_fetch_buffer_size |
---|---|
デフォルト |
js_fetch_buffer_size 16k; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.4で登場しました。
Fetch APIでの読み書きに使用するバッファのsize
を設定します。
構文 |
js_fetch_ciphers |
---|---|
デフォルト |
js_fetch_ciphers HIGH:!aNULL:!MD5; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.0で登場しました。
Fetch APIを使用したHTTPSリクエストで有効な暗号を指定します。暗号はOpenSSLライブラリで理解される形式で指定されます。
完全なリストは、「openssl ciphers
」コマンドを使用して表示できます。
構文 |
js_fetch_max_response_buffer_size |
---|---|
デフォルト |
js_fetch_max_response_buffer_size 1m; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.4で登場しました。
Fetch APIで受信したレスポンスの最大size
を設定します。
構文 |
js_fetch_protocols [ |
---|---|
デフォルト |
js_fetch_protocols TLSv1 TLSv1.1 TLSv1.2; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.0で登場しました。
Fetch APIを使用したHTTPSリクエストで指定されたプロトコルを有効にします。
構文 |
js_fetch_timeout |
---|---|
デフォルト |
js_fetch_timeout 60s; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.4で登場しました。
Fetch APIの読み書きのタイムアウトを定義します。タイムアウトは、応答全体ではなく、連続する2つの読み取り/書き込み操作の間でのみ設定されます。この時間内にデータが送信されない場合、接続は閉じられます。
構文 |
js_fetch_trusted_certificate |
---|---|
デフォルト | — |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.0で登場しました。
Fetch APIでHTTPS証明書を検証するために使用される、PEM形式の信頼できるCA証明書を含むfile
を指定します。
構文 |
js_fetch_verify |
---|---|
デフォルト |
js_fetch_verify on; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.4で登場しました。
Fetch APIを使用して、HTTPSサーバー証明書の検証を有効または無効にします。
構文 |
js_fetch_verify_depth |
---|---|
デフォルト |
js_fetch_verify_depth 100; |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.0で登場しました。
Fetch APIを使用したHTTPSサーバー証明書チェーンの検証深度を設定します。
構文 |
js_header_filter |
---|---|
デフォルト | — |
コンテキスト |
location , if in location , limit_except |
このディレクティブはバージョン0.5.1で登場しました。
njs関数をレスポンスヘッダーフィルターとして設定します。このディレクティブを使用すると、レスポンスヘッダーの任意のヘッダーフィールドを変更できます。
js_header_filter
ハンドラーは結果をすぐに返すため、同期操作のみをサポートします。したがって、r.subrequest()やsetTimeout()などの非同期操作はサポートされていません。
このディレクティブは、ifブロック内で0.7.7以降に指定できます。
構文 |
js_import |
---|---|
デフォルト | — |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.4.0で登場しました。
njsでロケーションハンドラーと変数ハンドラーを実装するモジュールをインポートします。export_name
は、モジュール関数にアクセスするための名前空間として使用されます。export_name
が指定されていない場合は、モジュール名が名前空間として使用されます。
js_import http.js;
ここでは、モジュール名http
がエクスポートへのアクセス時の名前空間として使用されます。インポートされたモジュールがfoo()
をエクスポートする場合、http.foo
を使用して参照します。
複数のjs_import
ディレクティブを指定できます。
このディレクティブは、0.7.7以降、server
およびlocation
レベルで指定できます。
構文 |
js_include |
---|---|
デフォルト | — |
コンテキスト |
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 |
---|---|
デフォルト | — |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.3.0で登場しました。
njsモジュールの追加パスを設定します。
このディレクティブは、0.7.7以降、server
およびlocation
レベルで指定できます。
構文 |
js_periodic |
---|---|
デフォルト | — |
コンテキスト |
location |
このディレクティブはバージョン0.8.1で登場しました。
定期的に実行するコンテンツハンドラーを指定します。ハンドラーは、最初の引数としてセッションオブジェクトを受け取り、ngxなどのグローバルオブジェクトにもアクセスできます。
オプションのinterval
パラメータは、2回の連続実行の間隔を設定します。デフォルトは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.dokyumento.jp/en/docs/njs/'); let body = await reply.text(); ngx.log(ngx.INFO, body); }
構文 |
js_preload_object |
---|---|
デフォルト | — |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.7.8で登場しました。
設定時にイミュータブルオブジェクトをプリロードします。name
は、njsコードでオブジェクトを使用できるグローバル変数の名前として使用されます。name
が指定されていない場合は、代わりにファイル名が使用されます。
js_preload_object map.json;
ここでは、map
がプリロードされたオブジェクトにアクセスする際の名前として使用されます。
複数のjs_preload_object
ディレクティブを指定できます。
構文 |
js_set |
---|---|
デフォルト | — |
コンテキスト |
http , server , location |
指定されたvariable
にnjs function
を設定します。0.4.0以降、モジュール関数を参照できます。
この関数は、指定されたリクエストで変数が最初に参照されたときに呼び出されます。正確なタイミングは、変数が参照されるフェーズによって異なります。これを使用して、変数評価に関係のないロジックを実行できます。たとえば、変数がlog_formatディレクティブでのみ参照される場合、そのハンドラーはログフェーズまで実行されません。このハンドラーは、リクエストが解放される直前にクリーンアップを実行するために使用できます。
0.8.6以降、オプションの引数nocache
が指定されている場合、ハンドラーは参照されるたびに呼び出されます。rewriteモジュールの現在の制限により、nocache
変数がsetディレクティブによって参照される場合、そのハンドラーは常に固定長の値を返す必要があります。
js_set
ハンドラーは結果をすぐに返すため、同期操作のみをサポートします。したがって、r.subrequest()やsetTimeout()などの非同期操作はサポートされていません。
このディレクティブは、0.7.7以降、server
およびlocation
レベルで指定できます。
構文 |
js_shared_dict_zone |
---|---|
デフォルト | — |
コンテキスト |
http |
このディレクティブはバージョン0.8.0で登場しました。
ワーカープロセス間で共有されるキーと値の辞書を保持する共有メモリ領域のname
とsize
を設定します。
デフォルトでは、共有辞書はキーと値に文字列を使用します。オプションのtype
パラメーターを使用すると、値の型を数値に再定義できます。
オプションのtimeout
パラメーターは、共有辞書のエントリがすべてゾーンから削除されるまでの時間(ミリ秒単位)を設定します。一部のエントリに異なる削除時間が必要な場合は、add、incr、およびsetメソッドのtimeout
引数で設定できます(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 |
---|---|
デフォルト | — |
コンテキスト |
http , server , location |
このディレクティブはバージョン0.5.3で登場しました。
書き込み可能な変数を宣言します。値には、テキスト、変数、およびそれらの組み合わせを含めることができます。この変数は、setディレクティブで作成された変数とは異なり、リダイレクト後も上書きされません。
このディレクティブは、0.7.7以降、server
およびlocation
レベルで指定できます。
リクエスト引数
各HTTP njsハンドラーは、リクエストオブジェクトという1つの引数を受け取ります。