• 售前

  • 售后

热门帖子
入门百科

利用njs模块在nginx设置中引入js脚本

[复制链接]
哈哈SE7 显示全部楼层 发表于 2022-1-7 16:38:24 |阅读模式 打印 上一主题 下一主题
目次


  • 前言
  • 一 安装 NJS 模块

    • 方法一: 动态加载 NJS 模块
    • 方法二: 编译时增长模块

  • 二 NJS模块运行环境的特点
  • 三 NJS 模块支持的指令及对应的处理阶段
  • 四 NJS 的简单用法示例
  • 五 NJS 支持的指令
  • 参考资料
  • 总结

前言

由于很多 web 开辟并不认识 lua 语言. 因此 nginx 推出了 njs 模块, 可以在 nginx 的设置中引入 js 脚本, 从而实现一些更复杂的 nginx 设置功能.
以下介绍 njs 模块的特性和用法

一 安装 NJS 模块

要求 nginx 的版本大于 1.9.11, 由于从该版本才开始支持 load_module 指令

方法一: 动态加载 NJS 模块

注意: 不同版本的 nginx 必要相应版本的 NJS 模块.
       
  • 将 ngx_http_js_module.so 文件放在nginx 根目次的 modules 目次下,   
  • 在 nginx.conf 中增长引入模块
  1. load_module modules/ngx_http_js_module.so;
  2. load_module modules/ngx_stream_js_module.so;
复制代码
方法二: 编译时增长模块

下载源码 https://hg.nginx.org/njs/?_ga=2.99259804.301589667.1638621670-451035464.1638621670
该仓库在mercurial中管理, 必要使用 hg 下令下载源码
  1. hg clone  http://hg.nginx.org/njs
复制代码
nginx 编译时增长如下设置
  1. ./configure --add-module=<path to njs>/njs/nginx
复制代码
二 NJS模块运行环境的特点


NJS 模块并不是运行一个 Nodejs, 因此 nginx js 只能像 lua 模块一样作为 nginx 的一个中间件, 无法独立作为一个完备的背景服务.
与前端同学认识的 node 或浏览器中运行环境不同. njs 并没有使用 v8 剖析引擎, nginx 官方基于 ECMAScript 语言规范定制了一个剖析引擎. 因此支持的语法和特性也与标准有所不同.
1. 每次请求时创建运行时环境, 请求结束时烧毁
node 运行时启动的虚拟机是常驻内存的, 且该虚拟机运行时会主动完成内存的垃圾接纳.
而 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 文件
  1. // 文件位置: [nginx根目录]/conf/logging.js
  2. // 文件内容: 解析请求, 打印出所有的请求头
  3. function logAllHeaders(r) {
  4.     var log = `${r.variables.time_iso8601} client=${r.remoteAddress} method=${r.method} uri=${r.uri} status=${r.status}`;
  5.     r.rawHeadersIn.forEach(h => log += ` in.${h[0]}=${h[1]}`);
  6.     r.rawHeadersOut.forEach(h => log += ` out.${h[0]}=${h[1]}`);
  7.     return log;
  8. }
  9. export default { logAllHeaders }
复制代码
  1. # nginx 的配置文件
  2. http {
  3.    js_import  logging.js;      # js_import 加载一个 js 脚本, 该文件放在nginx 配置文件的目录下. js 的文件名会作为该模块的命名空间. 引用函数时可以通过[文件名].[函数名]的方式来引用
  4.    js_set     $log_all_headers logging.logAllHeaders; # js_set 把js文件中的函数 logAllHeaders 的输出保存到变量 $log_all_headers.
  5.    log_format kvpairs $log_all_headers;          # 自定义一种日志格式 kvpairs
  6.     server {
  7.         listen 80;
  8.         access_log /var/log/nginx/access.log kvpairs; # 设置该规则下的日志格式为上面自定义的格式
  9.         root /usr/share/nginx/html;
  10.     }
  11. }
复制代码
五 NJS 支持的指令

参考文档
NJS 支持的指令并不多. 要实现复杂的功能必要与 Nginx 的其他指令结合一起使用.
以下介绍几个常用的指令
js_body_filter 修改 response 的 body
  1. Syntax:        js_body_filter function | module.function [buffer_type=string | buffer];
  2. Default:        —
  3. Context:        location, limit_except
  4. This directive appeared in version 0.5.2.
复制代码
示例
  1. /**
  2. * 处理 response body 的函数
  3. * @param { object } r - http 对象
  4. * @param { buffer_type } data - 请求的 body 的数据
  5. * @param { boolean } flags - 是否是最后一个数据块
  6. */
  7. function filter(r, data, flags) {
  8.     r.sendBuffer(data.toLowerCase(), flags);
  9. }
复制代码
js_content 处理请求的返回
  1. Syntax:        js_content function | module.function;
  2. Default:        —
  3. Context:        location, limit_except
复制代码
示例
  1. http {
  2.     # 引入 js 模块
  3.     js_import  http.js;                 
  4.     server {
  5.         listen 80;
  6.         location /content {
  7.             # 通过 js_content 指令指定要执行的 js 函数
  8.             js_content http.content;
  9.         }
  10.     }
  11. }
复制代码
  1. // http.js 文件
  2. function content(r) {
  3.     r.status = 200;
  4.     r.headersOut['Content-Type'] = "text/plain; charset=utf-8";
  5.     r.headersOut['Content-Length'] = 12;
  6.     r.sendHeader();
  7.     r.send("I am content");
  8.     r.finish()
  9. }
  10. export default { content }
复制代码
js_header_filter 修改返回的请求头
  1. Syntax:        js_header_filter function | module.function;
  2. Default:        —
  3. Context:        location, limit_except
  4. This directive appeared in version 0.5.1.
复制代码
js_import 导入一个 js 文件
  1. Syntax:        js_import module.js | export_name from module.js;
  2. Default:        —
  3. Context:        http
  4. This directive appeared in version 0.4.0.
复制代码
示例
  1. http {
  2.     # 引入 js 模块. 文件名会作为该模块的命名空间. 引用函数时可以通过[文件名].[函数名]的方式来引用
  3.     js_import  http.js;                 
  4.     server {
  5.         listen 80;
  6.         location /content {
  7.             # 通过 js_content 指令指定要执行的 js 函数
  8.             js_content http.content;
  9.         }
  10.     }
  11. }
复制代码
js_set 设置变量
  1. Syntax:        js_set $variable function | module.function;
  2. Default:        —
  3. Context:        http
复制代码
该指令引用的函数会在变量第一次被引用时执行. 并且函数内仅支持同步的操纵

参考资料

       
  • NJS 支持的js语法: https://nginx.org/en/docs/njs/compatibility.html?_ga=2.128028686.301589667.1638621670-451035464.1638621670   
  • Harnessing the Power and Convenience of JavaScript for Each Request with the NGINX JavaScript Module:  https://www.nginx.com/blog/harnessing-power-convenience-of-javascript-for-each-request-with-nginx-javascript-module   
  • NJS模块文档: http://nginx.org/en/docs/http/ngx_http_js_module.html#example   
  • 源码: https://hg.nginx.org/njs/?_ga=2.99259804.301589667.1638621670-451035464.1638621670   
  • NJS 内置的对象, 方法, 函数: https://nginx.org/en/docs/njs/reference.html   
  • NJS 用法示例: https://github.com/nginx/njs-examples/#hello-world-example-http-hello

总结

到此这篇关于使用njs模块在nginx设置中引入js脚本的文章就介绍到这了,更多干系nginx设置引入js脚本内容请搜刮脚本之家从前的文章或继承浏览下面的干系文章渴望各人以后多多支持脚本之家!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作