自从在2015(原名 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
或流
上下文中声明相关变量(使用js_import
、 js_path
、 js_set
和js_var
指令),相当于在主文件顶部声明全局变量。 但实际调用 JavaScript 函数和变量的指令出现在子上下文中 - 例如,HTTP location{}
块中的js_content
指令和 Stream server{}
块中的js_access
指令。 这会产生两个问题:
http
和流
上下文中的声明本质上是噪音,因为没有迹象表明相关代码和变量实际在哪里使用。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
属性是一个布尔标志,对于内部请求(由包含内部
指令的location{}
块处理)设置为“true”。 当脚本使用可以在内部和非内部上下文中调用的通用事件处理程序时,您可以使用r.internal
标志来分叉逻辑。
以下归类为内部请求:
error_page
、 index
、 random_index
和try_files
指令重定向的请求X-Accel-Redirect
响应标头从上游服务器重定向的请求auth_request
和mirror
指令、 ngx_http_addition_module模块中的指令或服务器端包含 (SSI)包含
虚拟
命令(由ngx_http_ssi_module模块支持)调用的子请求重写
指令更改的请求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
的以下属性已被实现(有关每个属性的必需和可选参数的信息,请参阅文档):
文件句柄
文件句柄.read()
文件句柄.stat()
文件句柄.write()
文件句柄.write()
文件句柄.close()
这些方法已更新为支持FileHandle
(有关每种方法的参数的信息,请参阅链接的文档):
通过 njs 0.7.7,我们让您的团队可以更轻松地处理和共享 njs 代码。 njs 指令的扩展上下文使得使用自定义 JavaScript 代码增强 NGINX 配置变得更加直接。 您可以首先转向 API 网关、反向代理或 Web 服务器 - 它们不仅仅是另一个中间件或边缘组件。 您可以通过 JavaScript、 TypeScript或第三方节点模块使其成为应用的一部分,而无需在堆栈中添加其他组件。 您所需要的只是 NGINX!
有疑问吗? 加入NGINX 社区 Slack并查看#njs-code-review频道以了解更多信息、提出问题并获取有关您的 njs 代码的反馈。
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”