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

Two implementations of front-end routing from vue-router

Table of contents Mode Parameters HashHistory Has...

Summary of web design experience and skills

■ Website theme planning Be careful not to make yo...

MySQL Tutorial: Subquery Example Detailed Explanation

Table of contents 1. What is a subquery? 2. Where...

Native js to achieve simple carousel effect

This article shares the specific code of js to ac...

A brief discussion on creating cluster in nodejs

Table of contents cluster Cluster Details Events ...

A Deeper Look at SQL Injection

1. What is SQL injection? Sql injection is an att...

Differences between this keyword in NodeJS and browsers

Preface Anyone who has learned JavaScript must be...

mysql 5.7.18 winx64 free installation configuration method

1. Download 2. Decompression 3. Add the path envi...

Detailed basic operations on data tables in MySQL database

Table of contents 1. View the tables in the curre...

Commonplace talk about MySQL event scheduler (must read)

Overview MySQL also has its own event scheduler, ...

Secondary encapsulation of element el-table table (with table height adaptation)

Preface During my internship at the company, I us...

Implementation of Webpack3+React16 code splitting

Project Background Recently, there is a project w...

N ways to align the last row of lists in CSS flex layout to the left (summary)

I would like to quote an article by Zhang Xinxu a...

How to express relative paths in Linux

For example, if your current path is /var/log and...