=encoding utf-8

=head1 NAME

ngx_http_js_module - Module ngx_http_js_module




=head1



The C<ngx_http_js_module> module is used to implement
location and variable handlers
in L<njs|index> —
a subset of the JavaScript language.





Download and install instructions are available
L<here|install>.




=head1 Example Configuration



The example works since
L<0.4.0|changes>.

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







The F<http.js> file:

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






=head1 Directives

=head2 js_body_filter


B<syntax:> js_body_filter I<I<C<module.function>>
[I<C<buffer_type>>=I<C<string>> E<verbar> I<C<buffer>>]>



B<context:> I<location>


B<context:> I<if in location>


B<context:> I<limit_except>



This directive appeared in version 0.5.2.





Sets an njs function as a response body filter.
The filter function is called for each data chunk of a response body
with the following arguments:


=over


=item C<r>




the L<HTTP request|reference> object



=item C<data>




the incoming data chunk,
may be a string or Buffer
depending on the C<buffer_type> value,
by default is a string.
Since L<0.8.5|changes>, the
C<data> value is implicitly converted to a valid UTF-8 string
by default.
For binary data, the C<buffer_type> value
should be set to C<buffer>.



=item C<flags>




an object with the following properties:

=over


=item C<last>




a boolean value, true if data is a last buffer.




=back






=back







The filter function can pass its own modified version
of the input data chunk to the next body filter by calling
L<C<r.sendBuffer()>|reference>.
For example, to transform all the lowercase letters in the response body:

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







If the filter function changes the length of the response body, the
C<Content-Length> response header (if present) should be cleared
in C<js_header_filter>
to enforce chunked transfer encoding:

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







To stop filtering and pass the data chunks to the client
without calling C<js_body_filter>,
L<C<r.done()>|reference>
can be used.
For example, to prepend some data to the response body:

    
    function prepend(r, data, flags) {
        r.sendBuffer("XXX");
        r.sendBuffer(data, flags);
        r.done();
    }








B<NOTE>

As the C<js_body_filter> handler
returns its result immediately, it supports
only synchronous operations.
Thus, asynchronous operations such as
L<r.subrequest()|reference>
or
L<setTimeout()|reference>
are not supported.







B<NOTE>

The directive can be specified inside the
L<if|ngx_http_rewrite_module> block
since L<0.7.7|changes>.








=head2 js_access


B<syntax:> js_access I<I<C<module.function>>>



B<context:> I<location>


B<context:> I<if in location>


B<context:> I<limit_except>



This directive appeared in version 0.9.9.





Sets an njs function as a handler in the
L<access phase|development_guide>.
Asynchronous operations such as
L<r.subrequest()|reference>,
L<ngx.fetch()|reference>,
and L<setTimeout()|reference>
are supported.





A handler that returns without calling
L<C<r.return()>|reference>
or
L<C<r.decline()>|reference>
grants access.
To deny access or send a custom response (for example, a redirect),
the handler may call
L<C<r.return()>|reference>.
To make the handler express no opinion, deferring the decision to other
access checkers under
L<C<satisfy any>|ngx_http_core_module>,
the handler may call
L<C<r.decline()>|reference>.





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









=head2 js_content


B<syntax:> js_content I<I<C<module.function>>>



B<context:> I<location>


B<context:> I<if in location>


B<context:> I<limit_except>





Sets an njs function as a location content handler.
Since L<0.4.0|changes>,
a module function can be referenced.






B<NOTE>

The directive can be specified inside the
L<if|ngx_http_rewrite_module> block
since L<0.7.7|changes>.








=head2 js_context_reuse


B<syntax:> js_context_reuse I<I<C<number>>>


B<default:> I<128>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.8.6.





Sets a maximum number of JS context to be reused for
L<QuickJS engine|engine>.
Each context is used for a single request.
The finished context is put into a pool of reusable contexts.
If the pool is full, the context is destroyed.







=head2 js_engine


B<syntax:> js_engine I<C<njs> E<verbar> C<qjs>>


B<default:> I<njs>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.8.6.





Sets a L<JavaScript engine|engine>
to be used for njs scripts.
The C<njs> parameter sets the njs engine, also used by default.
The C<qjs> parameter sets the QuickJS engine.






B<NOTE>

The C<njs> engine is deprecated
since L<1.0.0|changes>;
new configurations should use the C<qjs>
(L<QuickJS|engine>) engine.








=head2 js_fetch_buffer_size


B<syntax:> js_fetch_buffer_size I<I<C<size>>>


B<default:> I<16k>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.4.





Sets the I<C<size>> of the buffer used for reading and writing
with L<Fetch API|reference>.







=head2 js_fetch_ciphers


B<syntax:> js_fetch_ciphers I<I<C<ciphers>>>


B<default:> I<HIGH:!aNULL:!MD5>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.0.





Specifies the enabled ciphers for HTTPS requests
with L<Fetch API|reference>.
The ciphers are specified in the format understood by the
OpenSSL library.





The full list can be viewed using the
“C<openssl ciphers>” command.







=head2 js_fetch_max_response_buffer_size


B<syntax:> js_fetch_max_response_buffer_size I<I<C<size>>>


B<default:> I<1m>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.4.





Sets the maximum I<C<size>> of the response received
with L<Fetch API|reference>.







=head2 js_fetch_protocols


B<syntax:> js_fetch_protocols I<
    [C<TLSv1>]
    [C<TLSv1.1>]
    [C<TLSv1.2>]
    [C<TLSv1.3>]>


B<default:> I<TLSv1 TLSv1.1 TLSv1.2>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.0.





Enables the specified protocols for HTTPS requests
with L<Fetch API|reference>.







=head2 js_fetch_timeout


B<syntax:> js_fetch_timeout I<I<C<time>>>


B<default:> I<60s>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.4.





Defines a timeout for reading and writing
for L<Fetch API|reference>.
The timeout is set only between two successive readE<sol>write operations,
not for the whole response.
If no data is transmitted within this time, the connection is closed.







=head2 js_fetch_trusted_certificate


B<syntax:> js_fetch_trusted_certificate I<I<C<file>>>



B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.0.





Specifies a I<C<file>> with trusted CA certificates in the PEM format
used to
L<verify|reference>
the HTTPS certificate
with L<Fetch API|reference>.







=head2 js_fetch_verify


B<syntax:> js_fetch_verify I<C<on> E<verbar> C<off>>


B<default:> I<on>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.4.





Enables or disables verification of the HTTPS server certificate
with L<Fetch API|reference>.







=head2 js_fetch_verify_depth


B<syntax:> js_fetch_verify_depth I<I<C<number>>>


B<default:> I<100>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.0.





Sets the verification depth in the HTTPS server certificates chain
with L<Fetch API|reference>.







=head2 js_fetch_proxy


B<syntax:> js_fetch_proxy I<I<C<url>>>



B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.9.4.





Configures a forward proxy URL
with L<Fetch API|reference>.
The I<C<url>> supports the HTTP scheme only
and can contain optional user credentials
in the format C<http:E<sol>E<sol>[user:password@]host:port>
for Basic authentication.
Supports both HTTP and HTTPS connections to destination servers.
If the I<C<url>> is empty, proxy routing is disabled.
The parameter value can contain variables.





Example:

    
    location /fetch {
        js_fetch_proxy http://user:pass@proxy.example.com:3128;
        js_content main.fetch_handler;
    }









=head2 js_fetch_keepalive


B<syntax:> js_fetch_keepalive I<I<C<connections>>>


B<default:> I<0>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.9.2.





Activates the cache for connections to destination servers.
When the value is greater than C<0>,
enables keepalive connections for
L<Fetch API|reference>.





The I<C<connections>> parameter sets the maximum number of idle
keepalive connections to destination servers that are preserved in the cache
of each worker process.
When this number is exceeded, the least recently used connections are closed.





Example:

    
    location /fetch {
        js_fetch_keepalive 32;
        js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
        js_content main.fetch_handler;
    }









=head2 js_fetch_keepalive_requests


B<syntax:> js_fetch_keepalive_requests I<I<C<number>>>


B<default:> I<1000>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.9.2.





Sets the maximum number of requests that can be served through one keepalive
connection with L<Fetch API|reference>.
After the maximum number of requests is made, the connection is closed.





Closing connections periodically is necessary to free per-connection memory
allocations.
Therefore, using too high maximum number of requests could result in
excessive memory usage and not recommended.







=head2 js_fetch_keepalive_time


B<syntax:> js_fetch_keepalive_time I<I<C<time>>>


B<default:> I<1h>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.9.2.





Limits the maximum time during which requests can be processed through one
keepalive connection with L<Fetch API|reference>.
After this time is reached, the connection is closed following the subsequent
request processing.







=head2 js_fetch_keepalive_timeout


B<syntax:> js_fetch_keepalive_timeout I<I<C<time>>>


B<default:> I<60s>


B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.9.2.





Sets a timeout during which an idle keepalive connection to a destination server
will stay open with L<Fetch API|reference>.







=head2 js_header_filter


B<syntax:> js_header_filter I<I<C<module.function>>>



B<context:> I<location>


B<context:> I<if in location>


B<context:> I<limit_except>



This directive appeared in version 0.5.1.





Sets an njs function as a response header filter.
The directive allows changing arbitrary header fields of a response header.






B<NOTE>

As the C<js_header_filter> handler
returns its result immediately, it supports
only synchronous operations.
Thus, asynchronous operations such as
L<r.subrequest()|reference>
or
L<setTimeout()|reference>
are not supported.







B<NOTE>

The directive can be specified inside the
L<if|ngx_http_rewrite_module> block
since L<0.7.7|changes>.








=head2 js_import


B<syntax:> js_import I<I<C<module.js>> E<verbar>
I<C<export_name from module.js>>>



B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.4.0.





Imports a module that implements location and variable handlers in njs.
The C<export_name> is used as a namespace
to access module functions.
If the C<export_name> is not specified,
the module name will be used as a namespace.

    
    js_import http.js;


Here, the module name C<http> is used as a namespace
while accessing exports.
If the imported module exports C<foo()>,
C<http.foo> is used to refer to it.





Several C<js_import> directives can be specified.





When C<js_import> is specified inside a
L<ngx_http_core_module>,
the imported modules are visible only if no JavaScript code
has been invoked earlier in the request.
A single VM is created per request when a
L</js_set> variable is first accessed
or when a L</js_content>, L</js_header_filter>,
L</js_body_filter>, or L</js_access> handler
is first invoked.
The VM is cloned from the configuration scope active at that moment,
and all subsequent JavaScript invocations within the request reuse it.
Thus, if any of the above is referenced before the request is mapped
to its final location, for example from a server-level
L<ngx_http_rewrite_module>,
the VM is bound to the import set of the outer scope, and modules
imported in the matched C<location> will not be visible.
To avoid this, declare such imports in a common parent scope.






B<NOTE>

The directive can be specified on the
C<server> and C<location> level
since L<0.7.7|changes>.








=head2 js_include


B<syntax:> js_include I<I<C<file>>>



B<context:> I<http>





Specifies a file that implements location and variable handlers in njs:

    
    nginx.conf:
    js_include http.js;
    location   /version {
        js_content version;
    }
    
    http.js:
    function version(r) {
        r.return(200, njs.version);
    }







The directive was made obsolete in version
L<0.4.0|changes>
and was removed in version
L<0.7.1|changes>.
The L</js_import> directive should be used instead.







=head2 js_load_http_native_module


B<syntax:> js_load_http_native_module I<I<C<path>> [C<as> I<C<name>>]>



B<context:> I<main>



This directive appeared in version 0.9.5.





Loads a L<native module|native_modules>
(shared library) for use in HTTP JavaScript code.
The directive is
L<QuickJS|engine>-only
and is not available when using the njs built-in JavaScript engine.





The I<C<path>> parameter
specifies the absolute path to the shared library file.
The optional C<as> I<C<name>> parameter
provides an alias name for importing the module in JavaScript code.
If not specified, the module can be imported using its filename.





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;
        # ... rest of http configuration
    }


In JavaScript code:

    
    // 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);








B<NOTE>

For security reasons, this directive is only allowed
in the C<main> configuration context.
Native modules run with full process privileges;
use absolute paths and ensure proper code review.








=head2 js_path


B<syntax:> js_path I<
I<C<path>>>



B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.3.0.





Sets an additional path for njs modules.






B<NOTE>

The directive can be specified on the
C<server> and C<location> level
since L<0.7.7|changes>.








=head2 js_periodic


B<syntax:> js_periodic I<I<C<module.function>>
        [C<interval>=I<C<time>>]
        [C<jitter>=I<C<number>>]
        [C<worker_affinity>=I<C<mask>>]>



B<context:> I<location>



This directive appeared in version 0.8.1.





Specifies a content handler to run at regular interval.
The handler receives a
L<session object|reference>
as its first argument,
it also has access to global objects such as
L<ngx|reference>.





The optional C<interval> parameter
sets the interval between two consecutive runs,
by default, 5 seconds.





The optional C<jitter> parameter sets the time within which
the location content handler will be randomly delayed,
by default, there is no delay.





By default, the C<js_handler> is executed on worker process 0.
The optional C<worker_affinity> parameter
allows specifying particular worker processes
where the location content handler should be executed.
Each worker process set is represented by a bitmask of allowed worker processes.
The C<all> mask allows the handler to be executed
in all worker processes.





Example:

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









=head2 js_preload_object


B<syntax:> js_preload_object I<I<C<name.json>> E<verbar>
I<C<name>> from I<C<file.json>>>



B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.7.8.





Preloads an
L<immutable object|preload_objects>
at configure time.
The C<name> is used as a name of the global variable
though which the object is available in njs code.
If the C<name> is not specified,
the file name will be used instead.

    
    js_preload_object map.json;


Here, the C<map> is used as a name
while accessing the preloaded object.





Several C<js_preload_object> directives can be specified.







=head2 js_set


B<syntax:> js_set I<
    I<C<$variable>>
    I<C<module.function>>
    [C<nocache>]>



B<context:> I<http>


B<context:> I<server>


B<context:> I<location>





Sets an njs C<function>
for the specified C<variable>.
Since L<0.4.0|changes>,
a module function can be referenced.





The function is called when
the variable is referenced for the first time for a given request.
The exact moment depends on a
L<phase|development_guide>
at which the variable is referenced.
This can be used to perform some logic
not related to variable evaluation.
For example, if the variable is referenced only in the
L<ngx_http_log_module> directive,
its handler will not be executed until the log phase.
This handler can be used to do some cleanup
right before the request is freed.





Since L<0.8.6|changes>,
if an optional argument C<nocache> is specified,
the handler is called every time it is referenced.
Due to current limitations
of the L<rewrite|ngx_http_rewrite_module> module,
when a C<nocache> variable is referenced by the
L<set|ngx_http_rewrite_module> directive
its handler should always return a fixed-length value.






B<NOTE>

As the C<js_set> handler
returns its result immediately, it supports
only synchronous operations.
Thus, asynchronous operations such as
L<r.subrequest()|reference>
or
L<setTimeout()|reference>
are not supported.







B<NOTE>

The directive can be specified on the
C<server> and C<location> level
since L<0.7.7|changes>.








=head2 js_shared_dict_zone


B<syntax:> js_shared_dict_zone I<
    C<zone>=I<C<name>>:I<C<size>>
    [C<timeout>=I<C<time>>]
    [C<type>=C<string>E<verbar>C<number>]
    [C<evict>]
    [C<state>=I<C<file>>]>



B<context:> I<http>



This directive appeared in version 0.8.0.





Sets the I<C<name>> and I<C<size>> of the shared memory zone
that keeps the
key-value L<dictionary|reference>
shared between worker processes.





By default the shared dictionary uses a string as a key and a value.
The optional C<type> parameter
allows redefining the value type to number.





The optional C<timeout> parameter sets
the time in milliseconds
after which all shared dictionary entries are removed from the zone.
If some entries require a different removal time, it can be set
with the C<timeout> argument of the
L<add|reference>,
L<incr|reference>, and
L<set|reference>
methods
(L<0.8.5|changes>).





The optional C<evict> parameter removes the oldest
key-value pair when the zone storage is exhausted.





The optional C<state> parameter specifies a I<C<file>>
that keeps the shared dictionary state
in JSON format and makes it persistent across nginx restarts
(L<0.9.1|changes>).





Example:

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









=head2 js_var


B<syntax:> js_var I<I<C<$variable>> [I<C<value>>]>



B<context:> I<http>


B<context:> I<server>


B<context:> I<location>



This directive appeared in version 0.5.3.





Declares
a L<writable|reference>
variable.
The value can contain text, variables, and their combination.
The variable is not overwritten after a redirect
unlike variables created with the
L<ngx_http_rewrite_module> directive.






B<NOTE>

The directive can be specified on the
C<server> and C<location> level
since L<0.7.7|changes>.








=head1 Request Argument



Each HTTP njs handler receives one argument, a request
L<object|reference>.




