您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“如何利用njs模塊在nginx配置中引入js腳本”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“如何利用njs模塊在nginx配置中引入js腳本”這篇文章吧。
要求 nginx 的版本大于 1.9.11, 因?yàn)閺脑摪姹静砰_始支持 load_module 指令
注意: 不同版本的 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
該倉(cāng)庫(kù)在mercurial中管理, 需要使用 hg 命令下載源碼
hg clone http://hg.nginx.org/njs
nginx 編譯時(shí)增加如下配置
./configure --add-module=<path to njs>/njs/nginx
NJS 模塊并不是運(yùn)行一個(gè) Nodejs, 因此 nginx js 只能像 lua 模塊一樣作為 nginx 的一個(gè)中間件, 無法獨(dú)立作為一個(gè)完整的后臺(tái)服務(wù).
與前端同學(xué)熟悉的 node 或?yàn)g覽器中運(yùn)行環(huán)境不同. njs 并沒有使用 v8 解析引擎, nginx 官方基于 ECMAScript 語言規(guī)范定制了一個(gè)解析引擎. 因此支持的語法和特性也與標(biāo)準(zhǔn)有所不同.
1. 每次請(qǐng)求時(shí)創(chuàng)建運(yùn)行時(shí)環(huán)境, 請(qǐng)求結(jié)束時(shí)銷毀
node 運(yùn)行時(shí)啟動(dòng)的虛擬機(jī)是常駐內(nèi)存的, 且該虛擬機(jī)運(yùn)行時(shí)會(huì)自動(dòng)完成內(nèi)存的垃圾回收.
而 NJS 會(huì)在每次請(qǐng)求時(shí)創(chuàng)建一個(gè)新的虛擬機(jī)并分配內(nèi)存, 在請(qǐng)求結(jié)束時(shí)銷毀該虛擬機(jī)并釋放內(nèi)存.
2. 非阻塞代碼執(zhí)行
njs 采用事件驅(qū)動(dòng)模型對(duì) NJS 運(yùn)行時(shí)環(huán)境進(jìn)行調(diào)度。當(dāng) NJS 執(zhí)行阻塞操作(例如讀取網(wǎng)絡(luò)數(shù)據(jù)或發(fā)出外部子請(qǐng)求)時(shí),Nginx 會(huì)掛起當(dāng)前 NJS VM 的執(zhí)行,并在事件完成時(shí)重新調(diào)度。因此 NJS 的代碼可以以簡(jiǎn)單的線性方式來寫
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. 集成請(qǐng)求處理過程
Nginx 對(duì)請(qǐng)求的處理包含多個(gè)階段. Nginx的指令通常在某個(gè)指定的階運(yùn)行對(duì)請(qǐng)求進(jìn)行處理. Nginx 的模塊也正是利用這個(gè)能力, 來調(diào)試或修改一個(gè)請(qǐng)求.
NJS 模塊也是通過指令的形式, 實(shí)現(xiàn)在特定的階段運(yùn)行 js 代碼邏輯.
處理階段 | 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 |
以下示例用 js 定義一種 log 的格式
在 Nginx 配置目錄下創(chuàng)建一個(gè) logging.js 文件
// 文件位置: [nginx根目錄]/conf/logging.js // 文件內(nèi)容: 解析請(qǐng)求, 打印出所有的請(qǐng)求頭 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 加載一個(gè) js 腳本, 該文件放在nginx 配置文件的目錄下. js 的文件名會(huì)作為該模塊的命名空間. 引用函數(shù)時(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 支持的指令并不多. 要實(shí)現(xiàn)復(fù)雜的功能需要與 Nginx 的其他指令結(jié)合一起使用.
以下介紹幾個(gè)常用的指令
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 對(duì)象 * @param { buffer_type } data - 請(qǐng)求的 body 的數(shù)據(jù) * @param { boolean } flags - 是否是最后一個(gè)數(shù)據(jù)塊 */ function filter(r, data, flags) { r.sendBuffer(data.toLowerCase(), flags); }
js_content 處理請(qǐng)求的返回
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 修改返回的請(qǐng)求頭
Syntax: js_header_filter function | module.function; Default: — Context: location, limit_except This directive appeared in version 0.5.1.
js_import 導(dǎo)入一個(gè) js 文件
Syntax: js_import module.js | export_name from module.js; Default: — Context: http This directive appeared in version 0.4.0.
示例
http { # 引入 js 模塊. 文件名會(huì)作為該模塊的命名空間. 引用函數(shù)時(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ù)會(huì)在變量第一次被引用時(shí)執(zhí)行. 并且函數(shù)內(nèi)僅支持同步的操作
以上是“如何利用njs模塊在nginx配置中引入js腳本”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。