【Node】认识一下Node.js 中的 VM 模块

前言

今天介绍 Node.js 中的 VM(Virtual Machine)模块的基本概念和使用方法。

很多人不太了解他,比如在下

所以本文也不会过于深入,会偏向入门!

小目标:看完之后向自己解释一下:啥是 VM 模块?它有什么作用?

什么是 VM 模块

VM 模块是 Node.js 内置的模块,用于在 V8 虚拟机上下文中编译和执行 JavaScript 代码。

说人话就是,VM 模块允许你在隔离的环境中运行 JavaScript 代码。

核心功能

这边用代码进行举例子,后面会介绍具体的使用场景

1. vm.runInThisContext(code)

在当前的全局上下文中执行代码,但【无法访问局部作用域】。

javascript 复制代码
const vm = require('vm')

const localVar = '本地变量'
const code = 'console.log(typeof localVar);' // 输出 "undefined"

vm.runInThisContext(code)

🤔 疑问:无法访问局部变量,那这个方法有啥意义???? 回答:公共的 API 可访问,比如 console, setTimeout, Buffer, JSON 等等。

2. vm.runInNewContext(code, sandbox)

在新的沙箱环境中执行代码,完全隔离。

javascript 复制代码
const vm = require('vm')

const sandbox = {
    animal: '猫',
    count: 2
}
const code = 'count += 1; console.log(animal + "有" + count + "只");'

vm.runInNewContext(code, sandbox)
console.log(sandbox.count) // 输出 3

补充:那公共 API 可以用吗?

回答:默认不能用公共 API,因为它创建了一个全新的、空白的沙箱环境,连全局对象都没有。

解决办法:手动把需要的全局对象传进去。

参考下面的代码:

javascript 复制代码
const sandbox = {
    x: 1,
    console: console, // 手动传入
    JSON: JSON, // 手动传入
    setTimeout: setTimeout // 手动传入
}

const code = `
  console.log('现在可以用了'); // 正常执行
  JSON.parse('{}');           // 正常执行
`

vm.runInNewContext(code, sandbox) // 正常工作

3. vm.runInContext(code, contextifiedSandbox)

在特定的上下文对象中执行代码。

javascript 复制代码
const vm = require('vm')

const sandbox = {x: 1}
vm.createContext(sandbox) // 上下文化沙箱

const code = 'x += 1; y = 2;'
vm.runInContext(code, sandbox)

console.log(sandbox) // 输出 { x: 2, y: 2 }

老问题:公共 API 可以用吗? 回答:取决于你怎么创建上下文。下面这样创建就可以!

js 复制代码
const vm = require('vm')

// 方式1:从空对象创建 - 不能用公共API
const emptySandbox = {}
vm.createContext(emptySandbox) // 空的上下文

// 方式2:传入全局对象 - 能用公共API
const globalSandbox = {console, JSON, setTimeout}
vm.createContext(globalSandbox) // 带全局能力的上下文

主要应用场景

  1. 代码沙箱:安全地执行不受信任的代码
  2. 模板引擎:动态执行模板逻辑,啥意思呢?其实就是说,你可以在运行时根据用户输入动态生成 HTML 或其他文本。
  3. 测试环境:创建隔离的测试上下文
  4. 插件系统:安全地运行第三方代码

⚠️ 注意事项

  • VM 不是绝对安全的,不能完全替代容器化技术。为啥都这样隔离了,还是不安全呢?因为 JavaScript 本身太灵活,总有办法通过原型链、异步回调等漏洞"逃"出沙箱,访问到主机的敏感信息或执行恶意代码。它防不住语言层面的漏洞攻击。这边暂时不展开。
  • 小贴士:使用 runInNewContext() 比 eval() 更安全
  • 谨慎处理异步操作和无限循环。啥意思?其实简单举个例子就是,你在沙箱中执行的代码不能包含无限循环,否则会导致 Node.js 进程挂起。

总结

Node.js 的 VM 模块提供了在隔离上下文中执行 JavaScript 代码的能力。通过不同的方法,你可以控制代码的执行环境和访问权限,实现安全的代码执行沙箱。

最后

回答开头的问题:啥是 VM 模块?它有什么作用?

Node.js 的 VM 模块就是个代码隔离箱------把不可信的代码关在笼子里运行,让它既能干活,又不会搞坏你的主程序。

相关推荐
蜗牛攻城狮2 小时前
微前端四大方案选型对比与最佳实践:qiankun、micro-app、wujie、Module Federation
前端·微前端·qiankun·前端架构·micro-app·wujie
学长毕设2 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
她说可以呀3 小时前
Vue插槽
前端·javascript·vue.js
qq_448011163 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
aixingpan3 小时前
aixingpan.cn API开发文档:前端查询夏令时和时区接口指南
前端·php
2601_958352904 小时前
23.5×19mm 换掉一整条音频链?|A-68 集成了什么:ADC / DAC / 24.576MHz 时钟 / AEC / 波束降噪,主控仅需 6 根线
前端·音视频·ai降噪·回声消除·语音模块
努力的小雨4 小时前
给 AI 眼镜开发应用有多难?我从零做了一个陪练,还上架了
后端
志尊宝5 小时前
AI原生前端开发(039):AI辅助的Nuxt 4全栈开发
前端·vue.js·ai-native
FRing035 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
excel6 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端