[小菜一碟] 在 Nginx 執行 JavaScript 的 encodeURIComponent 方法來做 URL Encode

之前的文章有介紹到 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_modulengx_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_importjs_set 語法把寫好的 JavaScript 程式載進來,js_import 是載入 js 檔案,使用 js_import 載入的 js 檔案必須與 nginx.conf 相同目錄,js_set 就像是宣告變數的概念。。

呼叫 JavaScript 程式

接著,我就攔截所有的 Request,將他們的 Query String 做 Url Encode 後當成參數傳給 /Home/Index 印出來,借此驗證 Work 不 Work?

參考資料

C# 指南 ASP.NET 教學 ASP.NET MVC 指引
Azure SQL Database 教學 SQL Server 教學 Xamarin.Forms 教學