返回顶部
首页 > 资讯 > 服务器 >利用njs模块在nginx配置中引入js脚本
  • 143
分享到

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

2024-04-02 19:04:59 143人浏览 独家记忆
摘要

目录前言一 安装 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 中增加引入模块

load_module modules/ngx_http_js_module.so;
load_module modules/ngx_stream_js_module.so;

方法二: 编译时增加模块

下载源码 https://hg.nginx.org/njs/?_ga=2.99259804.301589667.1638621670-451035464.1638621670

该仓库在mercurial中管理, 需要使用 hg 命令下载源码


hg clone  http://hg.nginx.org/njs

nginx 编译时增加如下配置


./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 文件


// 文件位置: [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_except
This directive appeared in version 0.5.2.

示例




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_except
This directive appeared in version 0.5.1.

js_import 导入一个 js 文件


Syntax:	js_import module.js | export_name from module.js;
Default:	—
Context:	http
This 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

该指令引用的函数会在变量第一次被引用时执行. 并且函数内仅支持同步的操作

参考资料

  • 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脚本内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 利用njs模块在nginx配置中引入js脚本

本文链接: https://lsjlt.com/news/161121.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 利用njs模块在nginx配置中引入js脚本
    目录前言一 安装 NJS 模块方法一: 动态加载 NJS 模块方法二: 编译时增加模块二 NJS模块运行环境的特点三 NJS 模块支持的指令及对应的处理阶段四 NJS 的简单用法示例...
    99+
    2024-04-02
  • 如何利用njs模块在nginx配置中引入js脚本
    这篇文章主要为大家展示了“如何利用njs模块在nginx配置中引入js脚本”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何利用njs模块在nginx配置中引入js脚本”这篇文章吧。一 安装 N...
    99+
    2023-06-22
  • Python 中怎么利用ConfigParser解析配置模块
    这篇文章将为大家详细讲解有关Python 中怎么利用ConfigParser解析配置模块,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。基本的读取配置文件-read(filename) 直接读...
    99+
    2023-06-04
  • 怎么在python中使用import语句引入模块
    今天就跟大家聊聊有关怎么在python中使用import语句引入模块,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C# ...
    99+
    2023-06-14
  • Python中怎么利用内置模块处理ini配置文件
    Python中怎么利用内置模块处理ini配置文件,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。注意:本文基于Python  3.9.0(CPython...
    99+
    2023-06-15
  • 怎么在Mac M1中利用Nginx实现多站点配置
    本篇文章为大家展示了怎么在Mac M1中利用Nginx实现多站点配置,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。第一步 : 设置 IP 与 域名 映射 (也就是增加 hosts)# 终端...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作