在单独的上下文中运行js代码并访问其全局变量

时间:2016-04-26 10:11:42

标签: javascript node.js

我想在节点中运行第三方JavaScript文件(我对其内容没有多少控制权),并在其上下文中访问由该文件的代码创建的全局变量。

我考虑过两件事:

  1. vm沙箱中运行代码。问题是我不知道正确如何创建上下文,因为vm.createContext([sandbox])不会自动提供基本的内容,例如console或{{ 1}}或者我想要运行的脚本。

    这有点令人失望,因为文档明确指出(强调我的):

      

    如果给出一个沙盒对象,那么" contextify"沙盒,以便它可以用于调用vm.runInContext()或script.runInContext()。在内部脚本运行时,沙箱将成为全局对象,保留其所有现有属性,但也具有内置对象和函数,任何标准全局对象都具有

    什么是"任何标准全局对象的内置对象和函数都有" ?我天真地假设它是requireconsoleprocess等等。但如果是这样,API就不起作用,因为它们是没有设置。我可能在这里误解了一些东西。

    require

    结果是:

      

    evalmachine.:1
      的console.log(FOO);
      ^
      ReferenceError:未定义控制台

  2. child process中运行代码。但我无法找到有关访问子进程的全局变量的任何文档。我假设与子进程进行通信的唯一方法是通过消息传递,但即使这似乎是从父对子,而不是反过来......

  3. 基本上,我被卡住了。 HALP。

3 个答案:

答案 0 :(得分:5)

您可以使用advanced vm/sandbox for Node.js

var VM = require('vm2').NodeVM; // https://github.com/patriksimek/vm2#nodevm

var options = {
    console: 'inherit',
    sandbox: {
        foo: 'foo'
    }
}

vm = new VM(options);

var code = `
    console.log(foo); 
    oldFoo = foo; 
    foo = Math.random();
`;

vm.run(code);

console.log(vm.context.oldFoo, vm.context.foo);

答案 1 :(得分:0)

如何在上下文中传递父级console

const vm = require('vm');

var sandbox = {
  console: console
};

var context = new vm.createContext(sandbox);
var script = new vm.Script('console.log("foo")');

script.runInContext(context);

答案 2 :(得分:0)

在此代码中,我们可以发送任何响应,并可以使用全局函数访问全局变量,并且可以访问从VM Sandbox返回的整个数据。

 function compiler(){
     let add = x*y
     Return (add);
 }
 compiler();

const vm = new NodeVM({
   sandbox: {
     Return(data) {
       console.log('Data:', data);
     },
     x : 10,=
     y : 20
   },
   require: {
     external: true,
     builtin: ["fs", "path"],
     root: "./",
     mock: {
       fs: {
         readFileSync() {
           return "Nice try!";
         }
       }
     }
   }
 });
 try {
   vm.run(req.query.code);
 } catch (error) {
   console.log("error: ", error);
 }