When JS meets Nginx
Many Web developers are not familiar with lua. Therefore, Nginx has introduced the NJS module, which can introduce JS scripts into Nginx configuration to implement some more complex Nginx configuration functions.
Install the NJS module
Nginx is required to be older than 1.9.11, since the load_module directive has only been supported since then
Method 1: Load the NJS module dynamically
Note: Different versions of Nginx require corresponding versions of the NJS module.
- Place the ngx_http_js_module.so file in the modules directory of the Nginx root directory,
- Add import module to nginx.conf
load_module modules/ngx_http_js_module.so;
load_module modules/ngx_stream_js_module.so;
Copy the code
Method two: add modules at compile time
- Download source code:
The repository is managed in Mercurial. You can download the source code hg clone http://hg.nginx.org/NJS using the hg command
- Nginx adds the following configuration at compile time
./configure --add-module=<path to NJS>/NJS/nginx
Copy the code
Second, the characteristics of the running environment of NJS module
NJS modules do not run a Nodejs, so Nginx JS can only be used as a middleware of Nginx like lua modules, not as a complete backend service.
1. The runtime environment is created at each request and destroyed at the end of the request
2. Non-blocking code execution
NJS uses an event-driven model to schedule the NJS runtime environment. When NJS performs a blocking operation (such as reading network data or making an external subrequest), Nginx suspends the execution of the current NJS VM and reschedule the event when it completes. So NJS code can be written in a simple linear fashion
3. Only partial ECAMA syntax is supported
NJS is based on the ECMAScript 5.1 specification and supports a list of syntax supported by some functions in ECMAScript 6 nginx.org/en/docs/NJS…
4. Tightly integrate request processing
Nginx processing a request involves several phases. Nginx directives usually run at a specified order to process requests. The Nginx module takes advantage of this ability to debug or modify a request. NJS module is also implemented in the form of instructions to run JS code logic at a specific stage.
NJS module support instructions and the corresponding processing stage
Processing phase | The HTTP module | The Stream module |
---|---|---|
Access – Authentication and access control | auth_request and js_content | js_access |
The Pre – read – read/write content | N/A | js_preread |
Filter – Read/write response during proxy | js_body_filter js_header_filter | js_filter |
Content – Send response to client | js_content | N/A |
Log/Variables — Evaluated on demand | js_set | js_set |
Four simple usage examples of NJS
The following example defines a log format in JS
Create a logging.js file in the Nginx configuration directory
// File location: [nginx root directory]/conf/logging.js
// File contents: parses the request and prints out all the request headers
function logAllHeaders(r) {
var log = `${r.variables.time_iso8601} client=${r.remoteAddress} method=${r.method} uri=${r.uri} status=${r.status}`;
r.rawHeadersIn.forEach(h= > log += ` in.${h[0]}=${h[1]}`);
r.rawHeadersOut.forEach(h= > log += ` out.${h[0]}=${h[1]}`);
return log;
}
export default { logAllHeaders }
Copy the code
# Nginx configuration file
http {
js_import logging.js; # js_import Loads a js script in the directory of the Nginx configuration file. The js file name will be used as the module namespace. A function can be referenced in the format of [file name].[function name]
js_set $log_all_headers logging.logAllHeaders; # js_set saves the output of the function logAllHeaders from the js file to the variable $log_all_headers.
log_format kvpairs $log_all_headers; # Customize a log format kvpairs
server {
listen 80;
access_log /var/log/nginx/access.log kvpairs; # set the log format under this rule to the custom format aboveroot /usr/share/nginx/html; }}Copy the code
Five NJS supported directives
Reference documentation
NJS does not support many directives. Complex functions need to be used in conjunction with other Nginx directives.
Here are some common commands
Js_body_filter Modifies the body of response
Syntax: js_body_filter function | module.function [buffer_type=string | buffer];
Default: —
Context: location, limit_except
This directive appeared in version 0.5.2.
Copy the code
The sample
/** * the function that handles the response body *@param { object } r- HTTP object *@param { buffer_type } data-Requested body data *@param { boolean } flags- Is the last data block */
function filter(r, data, flags) {
r.sendBuffer(data.toLowerCase(), flags);
}
Copy the code
Js_content handles the return of the request
Syntax: js_content function | module.function;
Default: —
Context: location, limit_except
Copy the code
The sample
http {
# Introduce JS modules
js_import http.js;
server {
listen 80;
location /content {
# Specify the JS function to execute via the js_content directive
js_contenthttp.content; }}}Copy the code
/ / HTTP js file
function content(r) {
r.status = 200;
r.headersOut['Content-Type'] = "text/plain; charset=utf-8";
r.headersOut['Content-Length'] = 12;
r.sendHeader();
r.send("I am content");
r.finish()
}
export default { content }
Copy the code
Js_header_filter modifies the returned request header
Syntax: js_header_filter function | module.function;
Default: —
Context: location, limit_except
This directive appeared in version 0.5.1.
Copy the code
Js_import imports a JS file
Syntax: js_import module.js | export_name from module.js;
Default: —
Context: http
This directive appeared in version 0.4.0.
Copy the code
The sample
http {
# Introduce JS modules. The file name is used as the module's namespace. A function can be referenced in the format of [file name].[function name]
js_import http.js;
server {
listen 80;
location /content {
# Specify the JS function to execute via the js_content directivejs_content http.content; }}}Copy the code
Js_set sets variables
Syntax: js_set $variable function | module.function; Default: - the Context: HTTPCopy the code
The function referenced by this directive is executed when the variable is first referenced. And only synchronous operations are supported within the function
AD time
At present, wechat data center has a small number of front-end HCS, mainly responsible for the development of wechat big data-related systems, such as scheduling, BI, visualization, etc. Interested students are welcome to contact [email protected]
The resources
- NJS supports THE JS syntax
- Harnessing the Power and Convenience of JavaScript for Each Request with the NGINX JavaScript Module
- NJS module documentation
- The source code
- NJS built-in objects, methods, functions
- The sample