利用njs模塊在nginx配置中引入js腳本
前言
由于許多 web 開發(fā)并不熟悉 lua 語言. 因此 nginx 推出了 njs 模塊, 可以在 nginx 的配置中引入 js 腳本, 從而實(shí)現(xiàn)一些更復(fù)雜的 nginx 配置功能.
以下介紹 njs 模塊的特性和用法
一 安裝 NJS 模塊
要求 nginx 的版本大于 1.9.11, 因為從該版本才開始支持 load_module 指令
方法一: 動態(tài)加載 NJS 模塊
注意: 不同版本的 nginx 需要相應(yīng)版本的 NJS 模塊.
- 將 ngx_http_js_module.so 文件放在nginx 根目錄的 modules 目錄下,
- 在 nginx.conf 中增加引入模塊
load_module modules/ngx_http_js_module.so; load_module modules/ngx_stream_js_module.so;
方法二: 編譯時增加模塊
下載源碼 https://hg.nginx.org/njs/?_ga=2.99259804.301589667.1638621670-451035464.1638621670
該倉庫在mercurial中管理, 需要使用 hg 命令下載源碼
hg clone http://hg.nginx.org/njs
nginx 編譯時增加如下配置
./configure --add-module=<path to njs>/njs/nginx
二 NJS模塊運(yùn)行環(huán)境的特點(diǎn)
NJS 模塊并不是運(yùn)行一個 Nodejs, 因此 nginx js 只能像 lua 模塊一樣作為 nginx 的一個中間件, 無法獨(dú)立作為一個完整的后臺服務(wù).
與前端同學(xué)熟悉的 node 或瀏覽器中運(yùn)行環(huán)境不同. njs 并沒有使用 v8 解析引擎, nginx 官方基于 ECMAScript 語言規(guī)范定制了一個解析引擎. 因此支持的語法和特性也與標(biāo)準(zhǔn)有所不同.
1. 每次請求時創(chuàng)建運(yùn)行時環(huán)境, 請求結(jié)束時銷毀
node 運(yùn)行時啟動的虛擬機(jī)是常駐內(nèi)存的, 且該虛擬機(jī)運(yùn)行時會自動完成內(nèi)存的垃圾回收.
而 NJS 會在每次請求時創(chuàng)建一個新的虛擬機(jī)并分配內(nèi)存, 在請求結(jié)束時銷毀該虛擬機(jī)并釋放內(nèi)存.
2. 非阻塞代碼執(zhí)行
njs 采用事件驅(qū)動模型對 NJS 運(yùn)行時環(huán)境進(jìn)行調(diào)度。當(dāng) NJS 執(zhí)行阻塞操作(例如讀取網(wǎng)絡(luò)數(shù)據(jù)或發(fā)出外部子請求)時,Nginx 會掛起當(dāng)前 NJS VM 的執(zhí)行,并在事件完成時重新調(diào)度。因此 NJS 的代碼可以以簡單的線性方式來寫
3. 只支持部分 ECAMA 規(guī)范的語法
NJS 基于ECMAScript 5.1 規(guī)范, 并支持 ECMAScript 6 中的部分函數(shù)
支持的語法列表 https://nginx.org/en/docs/NJS/compatibility.html?_ga=2.91935000.301589667.1638621670-451035464.1638621670
4. 集成請求處理過程
Nginx 對請求的處理包含多個階段. Nginx的指令通常在某個指定的階運(yùn)行對請求進(jìn)行處理. Nginx 的模塊也正是利用這個能力, 來調(diào)試或修改一個請求.
NJS 模塊也是通過指令的形式, 實(shí)現(xiàn)在特定的階段運(yùn)行 js 代碼邏輯.
三 NJS 模塊支持的指令及對應(yīng)的處理階段
| 處理階段 | HTTP 模塊 | Stream 模塊 |
|---|---|---|
| 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 |
四 NJS 的簡單用法示例
以下示例用 js 定義一種 log 的格式
在 Nginx 配置目錄下創(chuàng)建一個 logging.js 文件
// 文件位置: [nginx根目錄]/conf/logging.js
// 文件內(nèi)容: 解析請求, 打印出所有的請求頭
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 的配置文件
http {
js_import logging.js; # js_import 加載一個 js 腳本, 該文件放在nginx 配置文件的目錄下. js 的文件名會作為該模塊的命名空間. 引用函數(shù)時可以通過[文件名].[函數(shù)名]的方式來引用
js_set $log_all_headers logging.logAllHeaders; # js_set 把js文件中的函數(shù) logAllHeaders 的輸出保存到變量 $log_all_headers.
log_format kvpairs $log_all_headers; # 自定義一種日志格式 kvpairs
server {
listen 80;
access_log /var/log/nginx/access.log kvpairs; # 設(shè)置該規(guī)則下的日志格式為上面自定義的格式
root /usr/share/nginx/html;
}
}
五 NJS 支持的指令
參考文檔
NJS 支持的指令并不多. 要實(shí)現(xiàn)復(fù)雜的功能需要與 Nginx 的其他指令結(jié)合一起使用.
以下介紹幾個常用的指令
js_body_filter 修改 response 的 body
Syntax: js_body_filter function | module.function [buffer_type=string | buffer]; Default: — Context: location, limit_except This directive appeared in version 0.5.2.
示例
/**
* 處理 response body 的函數(shù)
* @param { object } r - http 對象
* @param { buffer_type } data - 請求的 body 的數(shù)據(jù)
* @param { boolean } flags - 是否是最后一個數(shù)據(jù)塊
*/
function filter(r, data, flags) {
r.sendBuffer(data.toLowerCase(), flags);
}
js_content 處理請求的返回
Syntax: js_content function | module.function; Default: — Context: location, limit_except
示例
http {
# 引入 js 模塊
js_import http.js;
server {
listen 80;
location /content {
# 通過 js_content 指令指定要執(zhí)行的 js 函數(shù)
js_content http.content;
}
}
}
// http.js 文件
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 修改返回的請求頭
Syntax: js_header_filter function | module.function; Default: — Context: location, limit_except This directive appeared in version 0.5.1.
js_import 導(dǎo)入一個 js 文件
Syntax: js_import module.js | export_name from module.js; Default: — Context: http This directive appeared in version 0.4.0.
示例
http {
# 引入 js 模塊. 文件名會作為該模塊的命名空間. 引用函數(shù)時可以通過[文件名].[函數(shù)名]的方式來引用
js_import http.js;
server {
listen 80;
location /content {
# 通過 js_content 指令指定要執(zhí)行的 js 函數(shù)
js_content http.content;
}
}
}
js_set 設(shè)置變量
Syntax: js_set $variable function | module.function; Default: — Context: http
該指令引用的函數(shù)會在變量第一次被引用時執(zhí)行. 并且函數(shù)內(nèi)僅支持同步的操作
參考資料
- NJS 支持的js語法: 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模塊文檔: http://nginx.org/en/docs/http/ngx_http_js_module.html#example
- 源碼: https://hg.nginx.org/njs/?_ga=2.99259804.301589667.1638621670-451035464.1638621670
- NJS 內(nèi)置的對象, 方法, 函數(shù): https://nginx.org/en/docs/njs/reference.html
- NJS 用法示例: https://github.com/nginx/njs-examples/#hello-world-example-http-hello
總結(jié)
到此這篇關(guān)于利用njs模塊在nginx配置中引入js腳本的文章就介紹到這了,更多相關(guān)nginx配置引入js腳本內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Centos7.3 安裝部署Nginx并配置https的方法步驟
這篇文章主要介紹了Centos7.3 安裝部署Nginx并配置https的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Nginx負(fù)載均衡/SSL配置的實(shí)現(xiàn)
這篇文章主要介紹了Nginx負(fù)載均衡/SSL配置的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
nginx快速部署一個網(wǎng)站服務(wù)(多域名+多端口)
本文主要介紹了nginx快速部署一個網(wǎng)站服務(wù),并實(shí)現(xiàn)多域名和多端口,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10
Nginx配置帶SSL認(rèn)證的轉(zhuǎn)發(fā)方式 (HTTPS請求)
本文詳細(xì)介紹了如何在Windows系統(tǒng)上安裝和配置Nginx以支持HTTPS,首先,下載并解壓Nginx和OpenSSL,并配置環(huán)境變量,然后,生成SSL證書和密鑰文件,并在Nginx配置文件中啟用SSL,最后,啟動Nginx并訪問配置的HTTPS路徑以驗證配置是否成功2026-01-01

