【问题标题】:Using The VM Module To Run Node.js Scripts: "ReferenceError: require is not a function"使用 VM 模块运行 Node.js 脚本:“ReferenceError: require is not a function”
【发布时间】:2016-10-25 08:28:45
【问题描述】:

我正在编写自己的自定义 node.js 服务器。它现在处理静态页面、AJAX GET、POST 和 OPTIONS 请求(后者用于 CORS),但我知道我为运行服务器端 GET 和 POST 脚本选择的方法不是最佳的 - 官方 node.js文档指出,启动大量子 node.js 进程是一个坏主意,因为它是一种资源匮乏的方法。它有效,但我知道可能有更好的方法来实现相同的结果。

所以,我选择了 VM 模块。我的第一个想法是,这将解决机器与子进程混乱的问题,并使我的服务器更具可扩展性。

有一个小问题。我的服务器端脚本,用于目录列表和将结果发送回浏览器等任务,从几个 require 语句开始加载所需的模块。

终于编写了读取脚本文件的代码,并将其传递给 vm.Script(),我现在遇到了一个错误:

"ReferenceError: require 不是函数"

我后来了解到,这样做的原因是 VM 为脚本启动了一个裸 V8 执行环境,而不是一个独立的 node.js 执行环境。为了实现我的想法,我需要 VM 为我提供一个单独的沙盒 node.js 执行环境。我如何做到这一点?

我的初步研究告诉我,我需要为 VM 执行环境提供其自己的 node.js 全局变量的单独副本,以便 require 按预期运行。我刚才提供的理解是否正确?如果是这样,我需要采取哪些步骤来执行此任务?

【问题讨论】:

  • 为什么这些脚本需要在虚拟机中运行?它们是由第三方提供的(因此您需要某种沙箱来运行它们)?
  • 它们目前是我自己的脚本,但其目的是使 Web 服务器也对第三方脚本安全。当我第一次发现它时,VM 中固有的沙盒概念听起来就像是一张票。另外,使用 VM 可以避免产生大量 node.js 子进程,正如我上面所说,官方 node,js 文档警告说,这是可伸缩性和资源消耗的坏主意。
  • 这种情况下看vm2,和vm类似,但更容易控制。
  • 看起来不错,但美中不足。它需要 node.js V6 或更高版本。我有兴趣使我的服务器与 V6 之前的版本兼容。
  • 这样的话,搜索sandbox,还有其他选择:)

标签: node.js virtual-machine require


【解决方案1】:

我的初步研究告诉我,我需要为 VM 执行环境提供其自己的 node.js 全局变量的单独副本,以便按预期需要函数

runInNewContext 是正确的,它不与“父”上下文共享全局变量(而不是 runInThisContext)。

要在脚本中提供require 的功能,您可以将其作为函数传递。其他本地人也是如此,例如console

const vm = require('vm');

let sandbox = {
  require,
  console
};

vm.runInNewContext(`

let util = require('util');
console.log(util.inspect(util));

`, sandbox);

除了直接传递 require 之外,您还可以传递一个实现模块白名单的函数(这样您就可以控制允许脚本加载哪些模块)。

【讨论】:

  • 太棒了 这看起来正是我所需要的!我现在就试一试!
  • 这个解决了。你的建议非常有效。我现在可以在我的脚本中使用 require 了。现在继续下一个问题。 :)
猜你喜欢
  • 2017-06-22
  • 1970-01-01
  • 2018-10-25
  • 2016-01-05
  • 2017-01-04
  • 2013-08-14
  • 2018-04-06
  • 1970-01-01
  • 2019-08-22
相关资源
最近更新 更多