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

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

示例

/**

* 处理 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_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脚本内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

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

    目录 前言 一 安装 NJS 模块 方法一: 动态加载 NJS 模块 方法二: 编译时增加模块 二 NJS模块运行环境的特点 三 NJS 模块支持的指令及对应的处理阶段 四 NJS 的简单用法示例 五 NJS 支持的指令 参考资料 总结 前言 由于许多 web 开发并不熟悉 lua 语言. 因此 nginx 推出了 njs 模块, 可以在 nginx 的配置中引入 js 脚本, 从而实现一些更复杂的 nginx 配置功能. 以下介绍 njs 模块的特性和用法 一 安装 NJS 模块 要求 ngi

  • python中利用h5py模块读取h5文件中的主键方法

    如下所示: import h5py import numpy as np #HDF5的写入: imgData = np.zeros((2,4)) f = h5py.File('HDF5_FILE.h5','w') #创建一个h5文件,文件指针是f f['data'] = imgData #将数据写入文件的主键data下面 f['labels'] = np.array([1,2,3,4,5]) #将数据写入文件的主键labels下面 f.close() #关闭文件 #HDF5的读取: f = h5

  • 在页面中引入js的两种方法(推荐)

    在页面中引入js有两种基本方式:在页面中嵌入js.引用外部js文件. 一.在页面中嵌入js 这是在页面使用js最简单的方式了,一般我在写个小测试的情况下会用这种方式. 把script元素写在</body>前面,script元素的内容就是js代码.像这样: <script> // 在这里写js function test(){ alert('说点什么呢'); } test(); </script> 二.引用外部js文件 引用外部js文件,可以使js文件和HTML文件相分离

  • VUE项目中引入JS文件的方法总结

    目录 1.在index.html页面使用script标签引入 2.在main.js中使用window.moduleName 使用 3.手动添加export 4. 使用import方式,把需要的js库中的方法挂载到全局 补充:Vue3如何引用全局JS文件 总结 在开发Vue项目的时候,有时需要使用一些非ES6格式的没有export的js库,可以有如下方法实现: 1.在index.html页面使用script标签引入 当然也可以使用cdn的地址.这样引入后的内容是全局的,可以在所有地方使用. <!D

  • Nginx配置中指令root和alias的区别浅析

    前言 最近在nginx上部署日志分析工具awstats时,在配置awstats分析结果可供网页浏览这步时,分析结果页面访问总是404.后来查阅了一些资料,发现是root和alias的用法区别没搞懂导致的,这里特地将这两者区别详尽道来,供大家学习参考. root和alias都可以定义在location模块中,都是用来指定请求资源的真实路径,比如: location /i/ { root /data/w3; } 请求 http://foofish.net/i/top.gif 这个地址时,那么在服务器

  • 利用noesis.Javascript开源组件.Net中执行javascript脚本

    界面如下: 然后,click filter button后的UI: 看,筛选出来了,代码如下(js能调C#写的UserInfo类的各个属性) 复制代码 代码如下: public class UserInfo    {        public string FirstName { get; set; }        public string LastName { get; set; }        public int Age { get; set; }        public ov

  • Nginx服务器中配置GeoIP模块来拦截指定国家IP

    最近有一个网站项目需求:需要屏蔽国内的方问请求.花时间研究了一下这方面的资料.目前找到的最佳方法就是使用 Nginx 的 GeoIP 模块来实现地区的识别.然后配置相关国家的 ISO 名称,禁止访问即可.记录一下相关过程. 编译 GeoIP 组件 maxmind 提供的免费版数据库已经可以满足需求,在使用数据库前,需要先编译 GeoIP 组件: wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP-1.4.8.tar.gz ./co

  • Nginx服务器中location配置的一些基本要点解析

    在这一篇文章里,我将介绍nginx关于location的处理,大家都知道Nginx配置文件里面会有很多的location,nginx的配置指令的作用域可以分为 main,server,location这3个种,实际上这3者不是依次包含的关系,而是相互独立的关系,比如一个只具有main级别作用域的指令,是不能写在某个server或者location内的,模块的某个指令可以同时具有main,server,location这3种作用域,另外每个模块有 main,srv,loc这3个级别的配置,一个模块

  • 浅析Nginx配置文件中的变量的编写使用

    nginx 的配置文件使用的就是一门微型的编程语言,许多真实世界里的 Nginx 配置文件其实就是一个一个的小程序.当然,是不是"图灵完全的"暂且不论,至少据我观察,它在设计上受 Perl 和 Bourne shell 这两种语言的影响很大.在这一点上,相比 Apache 和 Lighttpd 等其他 Web 服务器的配置记法,不能不说算是 Nginx 的一大特色了.既然是编程语言,一般也就少不了"变量"这种东西(当然,Haskell 这样奇怪的函数式语言除外了).

  • php + nginx项目中的权限详解

    本文给大家介绍的关于php + nginx项目权限的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: nginx/php-fpm 进程权限 主进程用户为启动的用户 子进程 1.nginx的用户为nginx.conf中配置的用户 2.php-fpm的用户为php-fpm.conf中配置的用户 如:启动nginx的是root,nginx中配置的user是nginx,那主进程就是root,子进程就是nginx 处理方式 以下访问均以nginx子进程进行 静态文件 步骤:nginx访问/inde

随机推荐