njs scripting 是什麼?
njs是JavaScript語言的子集,它允許擴展nginx功能。 njs的創建符合 ECMAScript 5.1 (嚴格模式)以及某些 ECMAScript 6 和更高版本的擴展。合規性還在不斷發展。
簡單說就是在nginx內使用JavaScript編寫簡單的服務端程序。
為什麼要選擇使用njs scripting
- 使用js開發,開發簡單。便於快速開發
- 部署容易,有個nginx就可以,不需要部署其他東西,對server的性能要求很低, 也容易和其他服務共存。
- 在API層面可以保持穩定,以後轉成其他實現,也不會影響前端。
njs scripting適用於在項目初期需要一些服務端的功能,但是只希望有一個簡單實現,能快速開發部署,對其他發麵沒什麼要求。但是希望API保持穩定,不希望以後升級服務端的時候前端也要跟著改。
njs scripting 實例
通過一個簡單實例來體驗njs scripting。這個實例的api如下:
http://xxx.xxx.xxx/fetch_data?offset=?&limit=?
從服務器獲取數據,offset是開始的位置,limit是一次獲取的數量, 在列表頁面或者瀑布流頁面常常需要類似的api進行展示。一般的實現是數據放在數據庫中,通過SQL獲取數據,然後發送給前端進行展示。一般需要一個應用服務器還有數據庫來做,這在有些項目中是沒必要的,開發部署都顯得過於復雜。
環境安裝配置
我是在ubuntu下安裝的, 直接用apt-get安裝
1
2
3
4
5
6
7
8
9
10
|
Add the following line to /etc/apt/sources.list:
deb https://nginx.org/packages/ubuntu/ focal nginx
Install GPG key of the repository:
# wget https://nginx.org/keys/nginx_signing.key
# sudo apt-key add nginx_signing.key
Update the package index:
# sudo apt-get update
Install nginx-module-njs deb package:
# sudo apt-get install nginx-module-njs
|
nginx的配置文件如下
1
2
3
4
5
6
7
8
9
10
11
12
|
js_import /path/to/jsfile.js; //你的JS文件的路徑
server {
server_name xxxx.com;
access_log /var/log/nginx/xxxx.com.access.log;
error_log /var/log/nginx/xxxx.com.error.log info; //使用 info 級別 可以打出log,便於開發中的調試
root /path/to/your/html;
location /xxxxx {
add_header Content-Type 'application/json';
js_content jsfile.your_func_name;
}
}
|
JS文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
function your_func_name(r) {
var offset = 0; //default offset
var limit = 20; //default limit
// r.log('r.args.offset=' + r.args.offset);
if(Number.isInteger(+r.args.offset)) {
offset = parseInt(r.args.offset);
}
r.log('offset=' + offset);
// r.log('r.args.limit=' + r.args.limit);
if(Number.isInteger(+r.args.limit)) {
limit = parseInt(r.args.limit);
}
r.log('limit=' + limit);
var fs = require('fs').promises;
fs.readFile("/path/data.json").
then((data) => {
var json = JSON.parse(data.toString());
var output = [];
for (var i = offset; (i < json.length) && (i < offset + limit); i++) {
r.log('i=' + i);
output.push(json[i]);
}
r.return(200, JSON.stringify(output));
}).catch((error) => r.return(400, error));
}
export default { your_func_name };
|
- r.args中可以獲取request中的參數,比如r.args.offset可以獲取 request (http://xxx.com/api_name?offset=1) 中 offset參數的值
- r.log可以輸出log,log會輸出到 nginx中設置的文件中, 注意log級別.
error_log /var/log/nginx/xxxx.com.error.log info; //使用 info 級別 可以打出log,便於開發中的調試
- r.return可以返回結果
- 實例中的數據保存在一個json文件中,api通過offset,limit輸出其中的一部分。
- 修改JS文件後,需要重啟nginx才會生效。
data.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[
{
"a": "v1",
"b": "v2",
"c": "v3"
},
{
"a": "v1",
"b": "v2",
"c": "v3"
},
{
"a": "v1",
"b": "v2",
"c": "v3"
}
]
|