自 2015 年推出 NGINX JavaScript 模块 (njs)(原名 nginScript)并于 2017<.htmla> 年正式发布以来,我们一直在不断增添新特性,并在数十个版本更新中持续完善我们的代码实现。通常,我们会等到 NGINX Plus 发布后再讨论新版 NGINX JavaScript 的特性,但这次我们对版本 0.7.7 充满期待,已经等不及了!
njs 0.7.7 的重要增强功能可让您的 NGINX 配置变得更加模块化、更加有序、更易于复用:
fs.FileHandle
对象使文件操作更有效率。如欲了解有关 njs 的更多信息并查看用例列表(提供示例代码),请参阅我们的博文《借助 NGINX JavaScript 模块,充分利用 JavaScript 的强大功能和便利性以快速处理每个请求》。
有关 njs 0.7.7 的所有新特性和漏洞修复的完整列表,请参阅《变更》文档。
在之前的 njs 版本中,您必须导入 JavaScript 代码,并在顶层 http 或 stream 上下文中声明相关变量(使用 js_import
、js_path
、js_set
和 js_var
指令),这相当于在主文件顶部声明全局变量。但实际调用 JavaScript 函数和变量的指令却出现在子上下文中 — 例如,http
location{}
块中的 js_content
指令,stream
server{}
块中的 js_access
指令。这会产生两个问题:
http
和 stream
上下文中的声明基本上是噪声,因为没有指明实际使用相关代码和变量的位置。http{}
和 stream{}
块,并使用 include
指令从 /etc/nginx/conf.d 和 /etc/nginx/stream.d 目录中读取较小的特定函数配置文件,但 NGINX 配置非常灵活 — 您可在多个文件中添加 http{}
和 stream{}
块。在有多人操作你的 NGINX 配置且并非总能遵循既定规则的环境中,这将是一个问题。在 njs 0.7.7 及更高版本中,您可在使用变量的上下文中导入代码并声明这些变量:
HTTP –
以下指令可以出现在 if
上下文及 location
和 limit_except
上下文中:
将特定用例的所有 njs 配置都放到单个文件中还可提高代码的模块化程度和可移植性。
例如,在之前的 njs 版本中,当添加一个新脚本时,您必须同时更改 nginx.conf(添加 js_import
并可能需要添加 js_path
、js_set
及 js_var
)和调用 JavaScript 函数的文件(此处为 jscode_local.conf)。
在 njs 0.7.7 或更高版本中,所有和 util 函数相关的配置都在 jscode_integrated.conf 这个文件中:
njs 0.7.7 的多个新特性允许您根据执行 JavaScript 代码的上下文(处理阶段)修改其行为。
r.internal
属性HTTP r.internal
属性是一个布尔标志,针对内部请求(由添加了 internal
指令的 location{}
块进行处理)设置为 “true”。当一个脚本使用能够在内部和非内部上下文中调用的一般事件处理程序时,您可使用 r.internal
标志来派生 (fork) 逻辑。
以下属于内部请求:
error_page
、index
、random_index
及 try_files
指令重定向的请求X-Accel-Redirect
响应标头重定向的请求auth_request
和 mirror
指令、ngx_http_addition_module 块中的指令或服务器端引用 (SSI) 引用虚拟命令(由 ngx_http_ssi_module 模块提供支持)调用的子请求rewrite
指令更改的请求s.send()
方法在早期 njs 版本中,Stream s.send()
方法具有上下文相关性,因为其数据发送方向取决于调用该方法的回调位置(上游或下游)。这适合同步回调(s.send()
最初专为同步回调而设计),但不适用于 ngx.fetch()
等异步函数。
在 njs 0.7.7 及更高版本中,数据发送方向被存储在单独的内部标志中,可供 s.send()
使用。
fs.FileHandle()
对象实现更高效的文件操作 文件系统模块 (fs
) 实现了对文件的操作。fs 模块中的新 FileHandle
对象是数字文件描述符的对象包装器。FileHandle
对象的实例使用 fs.promises.open()
方法创建而成。
使用 FileHandle
对象获取一个文件描述符,便可用于:
read()
和 write()
等函数已实现 FileHandle
的以下属性(有关每个属性的必选和可选参数的信息,请参阅文档):
filehandle.fd
filehandle.read()
filehandle.stat()
filehandle.write()
filehandle.write()
filehandle.close()
以下方法已经更新,可支持 FileHandle
(请参阅链接文档,获取有关每个方法的参数信息):
fs.openSync()
fs.promises.open()
fs.fstatSync()
fs.readSync()
fs.writeSync()
(buffer)fs.writeSync()
(string)
借助 njs 0.7.7,您的团队能够更轻松地操作和共享 njs 代码。njs 指令的扩展上下文让使用自定义 JavaScript 代码来增强 NGINX 配置变得更加简单。
您可以将其用于 API网关、反向代理或 Web 服务器 — 不只是中间件或边缘组件。您可以通过 JavaScript、TypeScript 或第三方节点模块让其成为您应用的一部分,而无需在堆栈中添加其他组件。只需使用 NGINX 即可!
有问题?请添加“小 N 助手(微信号:nginxoss)”加入到我们的官方微信群,以了解更多信息、提出问题并获得有关您 njs 代码的反馈。
"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."