Node.js vm.runInContext() 方法

21 Feb 2025 | 阅读 6 分钟

Node.js 是一个强大的框架,可以在服务器端运行 JavaScript 编程语言。它提供了许多内置模块来支持开发活动。其中之一是 VM(虚拟机)模块,它允许在独立的环境中运行 JavaScript 代码。这种隔离可以防止正在 VM 中运行的代码影响到应用程序的其余部分,从而提高安全性和模块化。

VM 模块提供的以下方法值得注意。vm.runInContext() 函数已被证明非常有用,因为它可以在特定的上下文中运行代码。本文将重点探讨 vm.runInContext() 方法的功能。

理解 vm.runInContext()

vm.runInContext() 方法可以在期望的上下文中调用脚本,从而允许定义全局变量和函数的值。此方法在执行应在与程序其余部分不同的上下文中运行的代码时特别有用。

语法

它具有以下语法:

参数

该方法接受三个参数,如上所述并将在下面解释

  • Code: 要编译和运行的 JavaScript 代码。
  • ContextifiedObject: 在编译和运行代码时,它被用作全局对象。
  • Options: 这是一个可选参数,接受一个对象或字符串。如果对象包含字符串,它将指定文件名并返回字符串。

它包含以下参数

  • Filename: 它有一个字符串引用。它定义了此脚本创建的堆栈跟踪中使用的文件名。默认情况下,它具有值 'evalmachine. anonymous'
  • LineOffset: 此字段包含一个数字,表示此脚本生成的堆栈跟踪中指示的行号的位置。其默认状态为零。
  • ColumnOffset: 这是一个数字,定义了此脚本生成的堆栈跟踪中表示的列号的偏移量。默认情况下,其值始终初始化为 0。
  • DisplayErrors: 它是布尔类型,即如果在代码编译过程中发生错误,并且导致错误的行代码与堆栈跟踪相关联,则为 true。在默认情况下,值为 true。
  • Timeout: 它包含一个整数,表示在终止执行之前执行指定代码所花费的毫秒数。如果执行被中断,将引发错误。此值必须是正整数,这是完全正确的。
  • BreakOnSigint: 它包含一个布尔值,这是一个只能有两个值之一的数据类型:True 或 False。如果为 true,则在提供 SIGINT(也称为 Ctrl+C)后将终止执行。如果上述函数的执行被中断,它将给出错误。默认情况下,其值为 false。

返回值

它可用于检索脚本处理并通过表达式语句的最后一个值。

以下示例演示了 Node.js 中 vm.runInContext() 方法的每种用法。

示例 1

输出

 
The output value is:  { count: 48 }   

说明

此代码演示了如何使用 Node.js vm 模块在给定作用域中运行 JavaScript 代码。它首先使用 vm 模块和一个具有属性 count 值为 12 的对象 conObj。然后调用 vm.createContext 函数从 conObj 创建一个沙箱上下文。之后,vm.runInContext 方法在此上下文中执行代码 'count *= 4;',从而将 count 属性的值从 12 更改为 48。最后,console.log 打印修改后的 conObj,结果输出为 { count: 48 }。此方法将演示如何使用 vm 模块在沙箱中运行代码,以避免损害应用程序。

示例 2

输出

 
{ name_of_school: 'M.S.L', number_of_students: 2358 }   

说明

提供的 Node.js 代码展示了 vm.runInContext() 函数在特定上下文中运行 JavaScript 代码的应用,以创建安全的执行环境。在代码执行之前,需要导入 vm 并定义一个上下文对象 conObj,该对象包含两个属性 name_of_school 和 number_of_students。之后,此上下文对象被传递给 vm.createContext(),后者创建一个沙箱上下文。调用 vm.runInContext() 方法,其中一个脚本引用 number_of_students 作为对象的属性名,并将其设置为表达式 3 * number_of_students 的结果,从而更改上下文中的属性值。然后将修改后的上下文对象记录到标准输出流以显示 number_of_students 的新值。

它演示了 vm.runInContext() 函数如何在沙箱单元中安全地执行修改对象某些位的代码。

应用

Node.js 中的 vm.runInContext() 方法非常有用,并且有多种实际用例,尤其是在需要执行代码的安全隔离时。以下是一些应用:

沙箱化不受信任的代码

  • 描述: 在不损害应用程序其余部分的完整性的情况下,使用 Google Maps API for Android 来处理不受信任的代码。
  • 用例: 用户可以编写和运行 JavaScript 脚本的网站和平台,例如 CodePen、JSFiddle。

动态代码评估

  • 描述: 在沙箱中测试由其他脚本动态生成代码。
  • 用例: 编译和运行来自模板、用户输入或配置文件代码的工具,例如模板引擎或构建工具。

测试和模拟

  • 描述: 为单元测试定义隔离空间并模拟依赖项。
  • 用例: 需要在隔离环境中运行测试用例以防止副作用的框架,例如 Jest 或 Mocha。

虚拟环境

  • 描述: 为应用程序的不同部分建立不同的执行上下文。
  • 用例: 应用程序的状态需要为每个插件或模块单独保存,并且这些状态不应相互影响。

配置和脚本

  • 描述: 通过在安全环境中执行特定脚本来更改应用程序的配置。
  • 用例: 通过执行脚本来控制应用程序运行时配置的自动化工具。

结论

总之,Node.js 中的 vm.runInContext() 方法是一项功能,允许在受限环境中安全地执行独立 JavaScript 代码。当脚本需要在不同条件下运行,或者执行环境需要与主应用程序隔离时,此方法非常有用,同时提高了安全性和模块化。通过使用 vm.createContext() 创建沙箱上下文,并使用 vm 在此上下文中运行代码来获取、设置和删除 data.runInContext(),开发人员可以安全地运行动态或不受信任的代码以及隔离的代码。

示例及其用例包括在沙箱中运行未经测试的代码、安全计算代码地址、提供测试环境、安全执行配置脚本以及安全动态代码评估。这些功能使得 vm.runInContext() 函数在需要不同执行沙箱的在线代码编辑器、测试框架和动态模板引擎等应用程序中非常有用。

上面提供的示例展示了 vm.runInContext() 方法如何用于在不执行影响整个应用程序的代码的情况下操作对象属性。它是当今服务器端 JavaScript 开发中最重要的方法之一,因为它允许我们在沙箱环境中安全地执行代码,从而提高灵活性和可维护性。