之前的文章有介紹到 SSR(Server Side Rendering)的服務 - rendertron,在官方文件有提到,如果我們轉發的網址有帶 Query String 的話,需要對 Query String 做 URL Encode,我的轉發邏輯是寫在 Nginx,所以這件事情最好就由 Nginx 來負責。
想不到、想不到,在 Nginx 居然能執行 JavaScript,Nginx 中有一個 nginScript
(簡稱 njs
) 的 Module 可以來幫我們做到這件事,大大地提升了 Nginx 的彈性,我們來看看怎麼用?
安裝 nginx-module-njs
我的作業系統是 CentOS 7,其他作業系統的話就請大家自行搜尋安裝方式了,如果我們沒有加入官方 Repo 的話,就在 /etc/yum.repos.d
資料夾底下新增 nginx.repo
檔案,將下面的內容寫到檔案裡面。
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
然後,直接用 YUM 安裝就可以了。
sudo yum install -y nginx-module-njs
動態載入 ngx_http_js_module
我們可以透過 rpm -ql nginx-module-njs
指令,得知 nginx-module-njs 提供兩個 Module:ngx_http_js_module
、ngx_stream_js_module
,我們需要的是 ngx_http_js_module,我們就在 nginx.conf 檔案中用 load_module 語法載進來。
撰寫 JavaScript 程式
官方有提供一些範例給我們參考,我就照著官方的範例在 /etc/nginx
資料夾底下新增 http.js
檔案,檔案內容如下:
function urlencoded_querystring(r) {
var querystring = Object.keys(r.args).reduce(function (accu, next) {
if (accu) {
return accu + "&" + next + "=" + r.args[next];
} else {
return next + "=" + r.args[next];
}
}, "");
return encodeURIComponent(querystring ? "?" + querystring : "");
}
export default { urlencoded_querystring };
要注意的是,我們不能隨意丟參數給 function,function 只有一個固定的參數是 HTTP Request Object,我們只有這個參數可以用,所以如果我們要做的事情已經超過這個範圍,那 njs Module 可能就不適合了。
載入 JavaScript 程式
我們回到 nginx.conf 檔案裡面,在 http
Context 中使用 js_import
及 js_set
語法把寫好的 JavaScript 程式載進來,js_import 是載入 js 檔案,使用 js_import 載入的 js 檔案必須與 nginx.conf 相同目錄,js_set 就像是宣告變數的概念。。
呼叫 JavaScript 程式
接著,我就攔截所有的 Request,將他們的 Query String 做 Url Encode 後當成參數傳給 /Home/Index
印出來,借此驗證 Work 不 Work?