溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何利用njs模塊在nginx配置中引入js腳本

發(fā)布時(shí)間:2021-12-29 10:28:08 來源:億速云 閱讀:132 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要為大家展示了“如何利用njs模塊在nginx配置中引入js腳本”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“如何利用njs模塊在nginx配置中引入js腳本”這篇文章吧。

    一 安裝 NJS 模塊

    要求 nginx 的版本大于 1.9.11, 因?yàn)閺脑摪姹静砰_始支持 load_module 指令

    方法一: 動(dòng)態(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;

    方法二: 編譯時(shí)增加模塊

    下載源碼 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)行環(huán)境的特點(diǎn)

    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 代碼邏輯.

    三 NJS 模塊支持的指令及對(duì)應(yīng)的處理階段

    處理階段HTTP 模塊Stream 模塊
    Access – Authentication and access controlauth_request and js_contentjs_access
    Pre-read – Read/write payloadN/Ajs_preread
    Filter – Read/write response during proxyjs_body_filter js_header_filterjs_filter
    Content – Send response to clientjs_contentN/A
    Log / Variables – Evaluated on demandjs_setjs_set

    四 NJS 的簡(jiǎn)單用法示例

    以下示例用 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 支持的指令

    參考文檔

    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è)資訊頻道!

    向AI問一下細(xì)節(jié)

    免責(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)容。

    AI