runInNewContext到底做了什么?

时间:2014-12-10 06:16:53

标签: javascript node.js

我目前正在学习一些代码库,并且它经常使用runInNewContext,我试着查找但没有正确的定义。

阅读official docs指定,我所能理解的是code已符合指定的sandbox。究竟是什么意思,例如,代码库中有一些代码类似于:

request(url, function(error, response, body) {
var subject = {}
try
  vm.runInNewContext(body, subject, url);
  deferred.resolve(subject);
catch _error
  console.log(_error);
}

这里到底发生了什么让我感到困惑。

看到这个,我试图通过传递一个不同的物体而不是身体来玩弄它,但是它吐出了“意外的标识符”。

1 个答案:

答案 0 :(得分:7)

runInNewContext创建一个新的" context"或"沙盒"代码运行的地方。

例如,假设您有一大堆要运行的代码,这些代码将作为字符串加载。只需eval - 字符串可能很危险,并且几乎无法控制此代码所具有的变量和全局变量。

因此,您可以创建一个沙箱,一个新的上下文,可以在其中运行此代码。此外,您可以预设"您想要的变量,无论是作为上下文还是将事物传递到上下文中的方式。

所以说你的代码是这样的:

var code = "var add = function(a,b){return a + b;}; add(one,two);";

这是一个以字符串形式定义的函数,它添加两个数字,然后主动添加onetwo。什么是onetwo?现在他们是未定义的。但是如果你在新的上下文中运行它,你可以(合理地)安全地运行字符串代码甚至定义onetwo

vm.runInNewContext(code,{one:1,two:2});

将导致代码运行add(1,2)。一个更有用的例子可能是保存它。

var result = 0, code = "var add = function(a,b){return a + b;}; result = add(one,two);";
vm.runInNewContext(code,{one:1,two:2,result:result});
console.log(result); // spits out 3

请注意,我们在沙盒上下文中创建了一个变量result,以便code中的代码可以设置它。

我在cansecurity的声明性授权中使用它,您可以在其中设置要评估的表达式,并且只有在结果为true时输出才会通过。 https://github.com/deitch/cansecurity查看https://github.com/deitch/cansecurity/blob/master/lib/declarative.js#L96

在那种情况下,我实际上取得了结果。例如,我的代码可能是

var str = "user.id === req.user || user.role === 'admin'";
var authorized = vm.runInNewContext(str,{user:{id:"10",name:"John"},user:{role:"member",id:"10"}, req:{user:"20"}});
console.log(authorized); // spits out false, because user.id !== req.user, and user.role !== "admin"