nginx njs:安裝模組、設定 js_set,並以 reload 套用來建立 JavaScript 變數

聯盟行銷揭露 Ver 3.1
聯盟行銷揭露 Ver 3.2(僅限行動版)
測試環境 RHEL 系列AlmaLinux 9.8Nginx 1.28 + Apache 2.4njs 0.9.4WP Rocket 3.23.5.12026-10-17 確認

nginx njs 是 nginx 官方模組,可在 nginx 設定中以 JavaScript 函式處理請求或產生變數值。在 Nginx + Apache 構成的伺服器上,為了統一請求網址的大小寫(這只靠 nginx 設定無法改變),以與已安裝 nginx 相同的版本安裝了 njs 模組,並把以 js_set 建立的變數放進快取檔案路徑,以 reload 套用而不需重新啟動。

範例函式只有一行,把韓文網址的百分比編碼改成小寫;從請求物件讀取標頭或參數值來建立變數,做法也一樣。

1️⃣ nginx njs 是什麼:用 JavaScript 擴充 nginx 功能的模組

njs 不是像 Node.js 那樣可以獨立執行的 JavaScript 執行環境,沒有啟動腳本或自己的事件迴圈;只有在 nginx 呼叫設定中指定的函式時才會執行程式碼,之後處理再回到 nginx。

nginx 呼叫 JavaScript 函式的位置是固定的:HTTP 請求與回應處理階段、TCP·UDP 工作階段處理階段、變數值計算,以及週期計時器。函式從 nginx 傳入的請求物件讀取網址、標頭與參數,再把結果以回應或變數值傳回。

HTTP 端的指令中,[js_import] 載入腳本檔案,[js_set] 產生變數值,[js_content] 產生回應本文,[js_header_filter] 與 [js_body_filter] 則加工回應標頭與本文。這次套用的指令是 [js_import] 與 [js_set] 兩個。

🧭 nginx 呼叫 njs 函式的位置
說明圖解
📌 呼叫位置
📥 請求
🖥️ nginx
處理階段 · 設定中指定的位置
js_set變數值計算
js_content回應本文
js_header_filter · js_body_filter回應標頭 · 本文加工
呼叫→
📜 njs 函式
nginx 傳入的請求物件
讀取網址 · 標頭 · 參數
↩️ 以變數值傳回
↩️ 以回應傳回
↩️ 以加工後的標頭 · 本文傳回
❌ 不會像 Node.js 那樣自行執行沒有啟動腳本 · 沒有自己的事件迴圈
傳回→
🖥️ nginx
繼續處理
變數值本次套用 · 放進快取檔案路徑
回應本文以函式產生的本文回應
回應標頭 · 本文以加工後的標頭與本文回應
📤 回應
[js_set] 在 nginx 計算變數值的位置呼叫函式,函式傳回的值就成為變數值,處理再回到 nginx。
[js_content] 在產生回應本文的位置呼叫函式,由 nginx 送出函式讀取請求物件後產生的回應。
[js_header_filter] 與 [js_body_filter] 在送出回應的階段呼叫函式,加工回應標頭與本文,加工結束後處理再回到 nginx。

njs 模組的預設引擎,實作範圍是 ECMAScript 5.1(strict mode)加上部分 ECMAScript 6 之後的功能。正規表示式取代與函式程度的字串處理,都能在這個範圍內運作。

2️⃣ 需要 njs 的情況:只靠 nginx 設定無法改變的變數值

WordPress 外掛 WP Rocket 會用小寫的百分比編碼命名韓文網址文章的快取資料夾,而瀏覽器會用大寫編碼同一個網址來請求。這台伺服器上運作著 WordPress 網站。

如果 nginx 直接用請求網址組成快取檔案路徑,大小寫會對不上而找不到檔案,請求就會交給 Apache 與 PHP。

只靠 nginx 設定無法把這個值改成小寫。[map] 只能從設定好的值中挑一個,無法轉換字串;而安裝前的 [nginx -V] 輸出與模組資料夾中也沒有 perl 或 lua 模組。

如果要改的網址只有幾個,用 [map] 對照表也能處理,但每次有新文章都得重建對照表並 reload。若每個網址都要用同一規則轉換成各自的值,一個 [js_set] 函式就能連新文章、標籤與分類的網址一併處理。

perl 模組的 [perl_set] 也能用在同一位置,儲存庫中也有與 nginx 配對的套件,但 nginx 官方文件將 perl 模組列為實驗性模組。

3️⃣ 安裝 nginx njs:與已安裝的 nginx 相同版本

只用模組套件名稱安裝,看起來只會加上 njs,但儲存庫中最新的 njs 需要最新的 nginx,所以 nginx 也會一起升級。安裝前確認時,沒有寫版本的安裝指令顯示了把 nginx 從 1.28.0 升到 1.30.6 的計畫。

所以要先確認目前安裝的 nginx 版本。

rpm -q nginx
nginx-1.28.0-1.el9.ngx.x86_64

儲存庫中有與每個 nginx 版本各自配對的 njs 套件;版本號中 + 前面是 nginx 版本,後面是 njs 版本。

dnf list --showduplicates nginx-module-njs | grep '1.28.0+'
nginx-module-njs.x86_64         1:1.28.0+0.9.4-1.el9.ngx           @nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.8.10-1.el9.ngx          nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.0-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.1-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.2-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.3-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.4-1.el9.ngx           nginx-stable

與 nginx 1.28.0 配對的版本有 0.8.10 到 0.9.4 共六個,最上面的 @nginx-stable 那行是已安裝的版本。安裝時選其中最新的 0.9.4,並寫出完整版本號。

dnf install nginx-module-njs-1:1.28.0+0.9.4-1.el9.ngx

已安裝的套件需要哪個 nginx 版本,可以用 rpm 確認。

rpm -q --requires nginx-module-njs | grep nginx
nginx-r1.28.0
rpm -ql nginx-module-njs | grep -v build-id
/usr/bin/njs
/usr/lib64/nginx/modules/ngx_http_js_module-debug.so
/usr/lib64/nginx/modules/ngx_http_js_module.so
/usr/lib64/nginx/modules/ngx_stream_js_module-debug.so
/usr/lib64/nginx/modules/ngx_stream_js_module.so
/usr/share/doc/nginx-module-njs
/usr/share/doc/nginx-module-njs/CHANGES
/usr/share/doc/nginx-module-njs/COPYRIGHT

安裝的檔案有 HTTP 模組、處理 TCP·UDP 的 stream 模組、各自的除錯版本,以及命令列工具 njs。這次設定只載入 HTTP 模組 [ngx_http_js_module.so] 一個檔案。

4️⃣ js_set 設定:從載入模組到快取檔案路徑

安裝套件後 nginx 也不會自動載入模組,nginx.conf 最上方必須有 [load_module] 這一行。依官方文件,[load_module] 是 main 區塊的指令,所以要放在 events·http 區塊之外。

📂 /etc/nginx/設定資料夾
nginx.conf最上方的 load_module — 載入模組
njs/rocket.js函式 lc — 只把百分比編碼改成小寫
conf.d/
rocket-njs.confhttp 區塊 — js_import · js_set
example.com.confserver 區塊 — 快取檔案路徑中的 $rocket_uri
# /etc/nginx/nginx.conf 最上方(events·http 區塊之外)
load_module modules/ngx_http_js_module.so;

轉換函式放在與設定檔分開的 .js 檔案中,由 nginx 設定載入最後一行以 export default 匯出的函式。

// /etc/nginx/njs/rocket.js — 只把百分比編碼 %XX 改成小寫
function lc(r) {
    return r.variables.request_uri.replace(/%[0-9A-F]{2}/g, function (m) { return m.toLowerCase(); });
}
export default { lc };

函式從請求物件 r 讀取 [request_uri] 變數,只把百分比符號後兩位是大寫的地方改成小寫再傳回。英文字母保持原樣,所以混有大寫的英文網址不會改變,這和 WP Rocket 命名快取資料夾的規則相同。

# http 區塊內(conf.d 中的 .conf 檔案)
js_import rkt from /etc/nginx/njs/rocket.js;
js_set $rocket_uri rkt.lc;

[js_import] 中的 rkt 是呼叫模組內函式用的名稱,[js_set] 把該函式的結果變成 [$rocket_uri] 變數。依官方文件,這個函式會在請求中第一次參照變數時執行,而且只支援同步處理。

# server 區塊 — 把快取檔案路徑的 $request_uri 換成 $rocket_uri
set $rocket_file '/wp-content/cache/wp-rocket/example.com${rocket_uri}index$rocket_mobile-https.html';

改動的只有組成快取檔案路徑的這一行,把登入 Cookie、查詢字串與 POST 請求排除在快取之外的判斷維持不變。

5️⃣ 套用與確認:reload 後的錯誤記錄與回應標頭

先執行設定檢查,通過後再 reload。

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
systemctl reload nginx

新加入的 [load_module] 這一行不必重新啟動,reload 就生效了。錯誤記錄中留下了初始化 njs 虛擬機器的一行,沒有 JavaScript 錯誤。

grep 'js vm init' /var/log/nginx/error.log | head -1
2026/10/17 18:21:35 [notice] 27992#27992: js vm init njs: 0000559FDF6D0E00

行尾的 njs 是使用中的引擎名稱。用 [nginx -t] 檢查設定時也會記錄同樣的行,所以要對照 reload 的時間確認。

curl -sI 'https://example.com/-/' | grep -i 'x-rocket\|content-type'
content-type: text/html
x-rocket-nginx-serving-file: HIT

即使是以大寫編碼的韓文網址,也帶有表示 nginx 已回應快取檔案的標頭。帶有查詢字串或登入 Cookie 的請求以及 POST 請求,套用後仍然不帶該標頭交給 PHP。

6️⃣ 還原 njs 與更新 nginx

要還原時,把快取檔案路徑中的 [$rocket_uri] 改回 [$request_uri],移除 [js_import]·[js_set] 設定檔與 [load_module] 這一行,再經過設定檢查後 reload。

# server 區塊 — 改回原本的變數
set $rocket_file '/wp-content/cache/wp-rocket/example.com${request_uri}index$rocket_mobile-https.html';

套件可以留著:沒有 [load_module] 這一行,nginx 就不會載入它;只有要完全刪除時才移除套件。

dnf remove nginx-module-njs

更新 nginx 時,njs 套件也必須一起升到與新 nginx 版本配對的版本。更新前,用 [dnf list --showduplicates] 確認儲存庫中是否有新 nginx 版本的 njs 配對。

🔢 FAQ & 推薦內容

nginx 官方文件從 1.0.0 版開始把預設的 njs 引擎列為即將淘汰(deprecated),並建議新設定使用支援 ES2023 的 QuickJS 引擎。引擎用 0.8.6 版起提供的 [js_engine qjs] 指令指定。本文的 0.9.4 安裝版以預設 njs 引擎套用,沒有改用 QuickJS 測試。

這是不需要 nginx、用來開發與除錯 njs 程式碼的獨立命令列工具(依官方文件)。它隨 nginx-module-njs 套件一起安裝,用 [njs -v] 確認版本會顯示與模組相同的 0.9.4。

如果只處理 HTTP 請求,[ngx_http_js_module] 一個就夠了。套件中也有處理 TCP·UDP 工作階段的 [ngx_stream_js_module],官方安裝文件說明要用 [load_module] 載入兩者中需要的模組。

🧭 WP Rocket 相關文章 文章 16 · 工具 3
📋 WP Rocket 設定教學 📄 WP Rocket MCP Server 📄 WP Rocket 韓文網址 📄 nginx njs 📄 WP Rocket 多語系快取 📄 gclid 快取
📄 WP Rocket 速度測試 📝 快取 · 優化外掛 📝 速度改善案例
📋 快取:定義與所有領域 📄 網站快取 & 伺服器內部快取
📋 BEST 主機 TOP 7 📄 快速主機 2026
🛠️ WordPress 偵測 🛠️ WHOIS 網域查詢 🛠️ 我的 IP 查詢

ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Prove your humanity: 9   +   9   =