nginx的JavaScript魔力:njs简介与实践

nginx的JavaScript魔力:njs简介与实践

njs(nginx JavaScript module)是nginx的一个强大扩展模块,允许用户使用JavaScript来定制nginx的行为。它是一个轻量级的JavaScript解释器,专门为nginx优化,以确保不会影响nginx的性能

什么是njs?

njs支持ECMAScript 5.1(严格模式)以及一些ECMAScript 6及后续版本的扩展。它使得用户可以在nginx的配置文件中使用JavaScript脚本来处理请求和响应,从而实现复杂的逻辑。

什么情况下使用njs?

njs通常用于以下场景:

  1. 复杂的访问控制和安全检查:在请求到达上游服务器之前,可以使用njs进行复杂的访问控制和安全检查。
  2. 响应头的操作:可以动态地修改响应头
  3. 异步内容处理和过滤:njs允许编写灵活的异步内容处理器和过滤器。
  4. OIDC认证和JWT处理:例如,使用njs实现OIDC认证流程和JWT处理

用来解决什么问题?

njs主要解决以下问题:

  • 灵活的请求和响应处理:通过JavaScript脚本,可以动态地处理请求和响应,实现复杂的逻辑。
  • 扩展nginx功能:njs允许用户通过JavaScript扩展nginx的功能,而不需要修改nginx的源代码。
  • 提高配置灵活性:通过njs,可以根据不同的条件动态调整nginx的配置和行为。

实践案例

Hello World示例

这是一个基本的"Hello World"脚本,展示如何使用njs返回一个简单的响应:

javascript 复制代码
// hello.js
function hello(r) {
    r.return(200, "Hello World!\n");
}
export default { hello };

在nginx配置文件中启用此脚本:

text 复制代码
http {
    js_import hello from '/path/to/hello.js';
    server {
        listen 80;
        location / {
            js_content hello.hello;
        }
    }
}

访问http://localhost/将显示"Hello World!"。

动态路由示例

使用njs实现动态路由,可以根据请求的参数选择不同的后端服务器:

javascript 复制代码
// dynamic_routing.js
function chooseBackend(r) {
    let backend;
    if (r.headersIn['X-Backend'] === 'A') {
        backend = 'http://backendA';
    } else if (r.headersIn['X-Backend'] === 'B') {
        backend = 'http://backendB';
    } else {
        r.return(404);
    }
    r.headersOut['X-backend'] = backend;
    r.return(200);
}
export default { chooseBackend };

在nginx配置文件中启用此脚本:

arduino 复制代码
text
http {
    js_import dynamic_routing from '/path/to/dynamic_routing.js';
    server {
        listen 80;
        location / {
            js_content dynamic_routing.chooseBackend;
        }
    }
}

通过设置请求头X-BackendAB来选择不同的后端服务器。

JWT签名示例

使用njs实现JWT签名,可以在nginx中处理认证逻辑:

javascript 复制代码
// jwt_sign.js
async function signJWT(r) {
    const secretKey = 'your_secret_key';
    const payload = { user: 'example' };
    const token = await crypto.subtle.sign(
        {
            name: 'HMAC',
            hash: 'SHA-256',
        },
        await crypto.subtle.importKey(
            'raw',
            new TextEncoder().encode(secretKey),
            {
                name: 'HMAC',
                hash: 'SHA-256',
            },
            false,
            ['sign']
        ),
        new TextEncoder().encode(JSON.stringify(payload))
    );
    r.return(200, btoa(String.fromCharCode.apply(null, new Uint8Array(token))));
}
export default { signJWT };

在nginx配置文件中启用此脚本:

text 复制代码
http {
    js_import jwt_sign from '/path/to/jwt_sign.js';
    server {
        listen 80;
        location /sign {
            js_content jwt_sign.signJWT;
        }
    }
}

访问http://localhost/sign将返回一个签名后的JWT令牌。

总的来说,njs为nginx提供了一个强大的扩展机制,使得用户可以使用JavaScript来定制nginx的行为,从而提高nginx的灵活性和可扩展性。

相关推荐
jump_jump3 分钟前
Ripple:一个现代的响应式 UI 框架
前端·javascript·前端框架
云上凯歌12 分钟前
02 Spring Boot企业级配置详解
android·spring boot·后端
夏天想12 分钟前
element-plus的输入数字组件el-input-number 显示了 加减按钮(+ -) 和 小三角箭头(上下箭头),怎么去掉+,-或者箭头
前端·javascript·vue.js
秋饼25 分钟前
【手撕 @EnableAsync:揭秘 SpringBoot @Enable 注解的魔法开关】
java·spring boot·后端
IT_陈寒33 分钟前
Python 3.12 新特性实战:这5个改进让我的开发效率提升40%
前端·人工智能·后端
利兄的视界34 分钟前
一步到位:M4 芯片 Mac 安装 PostgreSQL 16 并适配 pgvector 教程
后端·postgresql
GZKING35 分钟前
ThinkPHP 8 报错"think\model\pivot" not found
后端
清风徐来QCQ1 小时前
SpringMvC
前端·javascript·vue.js
Smoothzjc1 小时前
👉 求你了,别再裸写 fetch 做 AI 流式响应了!90% 的人都在踩这个坑
前端·人工智能·后端
Swift社区1 小时前
ArkTS Web 组件里,如何通过 javaScriptProxy 让 JS 同步调用原生方法
开发语言·前端·javascript