Use the njs module to introduce js scripts in nginx configuration

Use the njs module to introduce js scripts in nginx configuration

Preface

Since many web developers are not familiar with the Lua language, nginx launched the njs module, which can introduce js scripts into the nginx configuration to achieve some more complex nginx configuration functions.

The following introduces the features and usage of the njs module

1. Install NJS module

Requires nginx version greater than 1.9.11, because load_module directive is only supported from this version

Method 1: Dynamically load NJS modules

Note: Different versions of nginx require corresponding versions of the NJS module.

  • Put the ngx_http_js_module.so file in the modules directory of the nginx root directory,
  • Add import module in nginx.conf
load_module modules/ngx_http_js_module.so;
load_module modules/ngx_stream_js_module.so;

Method 2: Add modules during compilation

Download source code https://hg.nginx.org/njs/?_ga=2.99259804.301589667.1638621670-451035464.1638621670

This repository is managed in mercurial, and you need to use the hg command to download the source code

hg clone http://hg.nginx.org/njs

Add the following configuration when compiling nginx

./configure --add-module=<path to njs>/njs/nginx

2. Characteristics of NJS module operating environment

The NJS module does not run a Nodejs, so nginx js can only be used as a middleware of nginx like the lua module, and cannot be used independently as a complete backend service.

Unlike the node or browser running environment that front-end students are familiar with, njs does not use the v8 parsing engine. Nginx officially customizes a parsing engine based on the ECMAScript language specification. Therefore, the supported syntax and features are also different from the standard.

1. Create a runtime environment for each request and destroy it when the request ends

The virtual machine started when the node is running is resident in the memory, and the memory garbage collection is automatically completed when the virtual machine is running.

NJS creates a new virtual machine and allocates memory for each request, and destroys the virtual machine and releases the memory 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 reschedules it when the event is completed. Therefore, the NJS code can be written in a simple linear manner

3. Only supports part of the ECAMA specification syntax

NJS is based on the ECMAScript 5.1 specification and supports some functions in ECMAScript 6

List of supported syntax https://nginx.org/en/docs/NJS/compatibility.html?_ga=2.91935000.301589667.1638621670-451035464.1638621670

4. Integration request processing

Nginx processes requests in multiple stages. Nginx instructions usually run at a specific stage to process the request. Nginx modules use this capability to debug or modify a request.

NJS module also uses instructions to run js code logic at a specific stage.

Three NJS module supported instructions and corresponding processing stages

Processing stage HTTP Module Stream Module
Access – Authentication and access control auth_request and js_content js_access
Pre-read – Read/write payload 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 uses js to define a log format

Create a logging.js file in the Nginx configuration directory

// File location: [nginx root directory]/conf/logging.js
// File content: parse the request and print out all 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 }
# nginx configuration file http {
   js_import logging.js; #js_import loads a js script, which is placed in the directory of the nginx configuration file. The js file name will be used as the namespace of the module. When referencing a function, you can reference it by [file name]. [function name] js_set $log_all_headers logging.logAllHeaders; #js_set saves the output of the function logAllHeaders in 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 customized format above root /usr/share/nginx/html;
    }
}

5. NJS supported commands

Reference Documentation

NJS does not support many instructions. To achieve complex functions, it needs to be used in combination with other Nginx instructions.

The following are some commonly used instructions

js_body_filter modifies the body of the 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.

Example

/**
* Function to process response body * @param { object } r - http object * @param { buffer_type } data - request body data * @param { boolean } flags - whether it is the last data block */

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

js_content handles the request response

Syntax: js_content function | module.function;
Default: —
Context: location, limit_except

Example

http {
    # Import js module js_import http.js;                 
    server {
        listen 80;
        location /content {
            # Specify the js function to be executed through the js_content instruction js_content http.content;
        }
    }
}
// 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 }

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.

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.

Example

http {
    # Import js module. The file name will be used as the namespace of the module. When referencing a function, you can reference it by [file name].[function name] js_import http.js;                 
    server {
        listen 80;
        location /content {
            # Specify the js function to be executed through the js_content instruction js_content http.content;
        }
    }
}

js_set sets variables

Syntax: js_set $variable function | module.function;
Default: —
Context: http

The function referenced by this instruction will be executed when the variable is referenced for the first time. And only synchronous operations are supported within the function

References

  • NJS supports js syntax: https://nginx.org/en/docs/njs/compatibility.html?_ga=2.128028686.301589667.1638621670-451035464.1638621670
  • Harnessing the Power and Convenience of JavaScript for Each Request with the NGINX JavaScript Module: https://www.nginx.com/blog/harnessing-power-convenience-of-javascript-for-each-request-with-nginx-javascript-module
  • NJS module documentation: http://nginx.org/en/docs/http/ngx_http_js_module.html#example
  • Source code: https://hg.nginx.org/njs/?_ga=2.99259804.301589667.1638621670-451035464.1638621670
  • NJS built-in objects, methods, functions: https://nginx.org/en/docs/njs/reference.html
  • NJS usage example: https://github.com/nginx/njs-examples/#hello-world-example-http-hello

Summarize

This is the end of this article about using the njs module to introduce js scripts in nginx configuration. For more relevant content about introducing js scripts in nginx configuration, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

<<:  MySQL database master-slave replication and read-write separation

>>:  Multiple ways to insert SVG into HTML pages

Recommend

Put frameset in body through iframe

Because frameset and body are on the same level, y...

Detailed explanation of Vue-router nested routing

Table of contents step 1. Configure routing rules...

Sharing the structure and expression principles of simple web page layout

Introduction to structure and performance HTML st...

Detailed explanation of Linux less command examples

less file name View File less file name | grep -n...

Tomcat8 uses cronolog to split Catalina.Out logs

background If the catalina.out log file generated...

How to check if data exists before inserting in mysql

Business scenario: The visitor's visit status...

The process of deploying and running countly-server in docker in win10

I have just come into contact with and become fam...

Summary of MySQL character sets

Table of contents Character Set Comparison Rules ...

Common considerations for building a Hadoop 3.2.0 cluster

One port changes In version 3.2.0, the namenode p...

SQL implementation of LeetCode (197. Rising temperature)

[LeetCode] 197.Rising Temperature Given a Weather...

Vue implements file upload and download

This article example shares the specific code of ...