下面介绍njs模块的特点和用法。
安装NJS模块时,nginx的版本应该大于1.9.11,因为只有从这个版本开始才支持load_module指令。
(资料图片)
【资料图】
方法一:动态加载NJS模块注意:不同版本的nginx需要相应版本的NJS模块。
Put the file ngx_http_js_module.so in the module directory of nginx root directory, and add the import module Load _ ModuleModules/NGX _ HTTP _ JS _ Module.so in nginx.conf; load _ module modules/ngx _ stream _ js _ module . so; Method 2: Add module download source code https://hg.nginx.org/njs/? at compile time. This is a good example. 58660.68686868661
仓库是在mercurial中管理的,下载源代码需要hg命令。
编译Hg clone http://hg.nginx.org/njsnginx.时添加了以下配置
. /configure-add-module=NJS/NJS/Nginx Path 2 Characteristics of NJS module running environment
NJS模块不运行一个Nodejs,所以nginx js只能像lua模块一样是nginx的一个中间件,不能独立成为一个完整的后台服务。
Njs没有使用v8解析引擎,但是nginx定制了一个基于ECMAScript语言规范的解析引擎,所以支持的语法和特性与标准不同。
1.在每次请求时创建一个运行时环境,并在请求结束时销毁它。
节点运行时启动的虚拟机是内存常驻的,虚拟机运行时会自动完成内存的垃圾回收。
NJS将在每次请求时创建一个新的虚拟机并分配内存,并在请求结束时销毁虚拟机并释放内存。
2.非阻塞代码执行
Njs采用事件驱动模型来调度NJS运行环境。当NJS执行阻塞操作(如读取网络数据或发出外部子请求)时,Nginx会暂停当前NJS VM的执行,并在事件完成时重新调度它。
因此,NJS的代码可以用简单的线性方式编写。
3.仅支持一些ECAMA标准语法。
NJS 基于ECMAScript 5.1 规范, 并支持ECMAScript 6 中的部分函数
支持的语法列表https://nginx.org/en/docs/NJS/compatibility.html?_ga=2.91935000.301589667.1638621670-451035464.1638621670
4. 集成请求处理过程
Nginx 对请求的处理包含多个阶段. Nginx的指令通常在某个指定的阶运行对请求进行处理. Nginx 的模块也正是利用这个能力, 来调试或修改一个请求.
NJS 模块也是通过指令的形式, 实现在特定的阶段运行js 代码逻辑.
三NJS 模块支持的指令及对应的处理阶段 处理阶段 HTTP 模块 Stream 模块 Access Authentication and access control auth_request and js_content js_access Pre-read Read/write payload N/A js_preread Filter Read/write response during proxy js_body_filter js_header_filter js_filter Content Send response to client js_content N/A Log/Variables Evaluated on demand js_set js_set 四NJS 的简单用法示例以下示例用js 定义一种log 的格式
在Nginx 配置目录下创建一个logging.js 文件
//文件位置: [nginx根目录]/conf/logging.js//文件内容: 解析请求, 打印出所有的请求头function logAllHeaders(r) { var log=`${r.variables.time_iso8601} client=${r.remoteAddress} method=${r.method} uri=${r.uri} status=${r.status}`; r.rawHeadersIn.forEach(h=log +=` in.${h[0]}=${h[1]}`); r.rawHeadersOut.forEach(h=log +=` out.${h[0]}=${h[1]}`); return log;}export default { logAllHeaders }# nginx 的配置文件http { js_import logging.js; # js_import 加载一个js 脚本, 该文件放在nginx 配置文件的目录下. js 的文件名会作为该模块的命名空间. 引用函数时可以通过[文件名].[函数名]的方式来引用 js_set $log_all_headers logging.logAllHeaders; # js_set 把js文件中的函数logAllHeaders 的输出保存到变量$log_all_headers. log_format kvpairs $log_all_headers; # 自定义一种日志格式kvpairs server { listen 80; access_log /var/log/nginx/access.log kvpairs; # 设置该规则下的日志格式为上面自定义的格式 root /usr/share/nginx/html; }}五NJS 支持的指令参考文档
NJS 支持的指令并不多. 要实现复杂的功能需要与Nginx 的其他指令结合一起使用.
以下介绍几个常用的指令
js_body_filter 修改response 的body
Syntax:js_body_filter function | module.function [buffer_type=string | buffer];Default:—Context:location, limit_exceptThis directive appeared in version 0.5.2.示例
/*** 处理response body 的函数* @param { object } r - http 对象* @param { buffer_type } data - 请求的body 的数据* @param { boolean } flags - 是否是最后一个数据块*/function filter(r, data, flags) { r.sendBuffer(data.toLowerCase(), flags);}js_content 处理请求的返回
Syntax:js_content function | module.function;Default:—Context:location, limit_except示例
http { # 引入js 模块 js_import http.js; server { listen 80; location /content { # 通过js_content 指令指定要执行的js 函数 js_content http.content; } }}//http.js 文件function content(r) { r.status=200; r.headersOut["Content-Type"]="text/plain; charset=utf-8"; r.headersOut["Content-Length"]=12; r.sendHeader(); r.send("I am content"); r.finish()}export default { content }js_header_filter 修改返回的请求头
Syntax:js_header_filter function | module.function;Default:—Context:location, limit_exceptThis directive appeared in version 0.5.1.js_import 导入一个js 文件
Syntax:js_import module.js | export_name from module.js;Default:—Context:httpThis directive appeared in version 0.4.0.示例
http { # 引入js 模块. 文件名会作为该模块的命名空间. 引用函数时可以通过[文件名].[函数名]的方式来引用 js_import http.js; server { listen 80; location /content { # 通过js_content 指令指定要执行的js 函数 js_content http.content; } }}js_set 设置变量
Syntax:js_set $variable function | module.function;Default:—Context:http该指令引用的函数会在变量第一次被引用时执行. 并且函数内仅支持同步的操作
本文[高级伪原创标题]到此分享完毕,希望对大家有所帮助。
标签: