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"
}
]
|