我想在节点中运行第三方JavaScript文件(我对其内容没有多少控制权),并在其上下文中访问由该文件的代码创建的全局变量。
我考虑过两件事:
在vm
沙箱中运行代码。问题是我不知道正确如何创建上下文,因为vm.createContext([sandbox])
不会自动提供基本的内容,例如console
或{{ 1}}或者我想要运行的脚本。
这有点令人失望,因为文档明确指出(强调我的):
如果给出一个沙盒对象,那么" contextify"沙盒,以便它可以用于调用vm.runInContext()或script.runInContext()。在内部脚本运行时,沙箱将成为全局对象,保留其所有现有属性,但也具有内置对象和函数,任何标准全局对象都具有。
什么是"任何标准全局对象的内置对象和函数都有" ?我天真地假设它是require
,console
,process
等等。但如果是这样,API就不起作用,因为它们是没有设置。我可能在这里误解了一些东西。
require
结果是:
evalmachine.:1
的console.log(FOO);
^
ReferenceError:未定义控制台
在child process中运行代码。但我无法找到有关访问子进程的全局变量的任何文档。我假设与子进程进行通信的唯一方法是通过消息传递,但即使这似乎是从父对子,而不是反过来......
基本上,我被卡住了。 HALP。
答案 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);
}