2016-07-02 4 views
0

問題:私はnodejs VMを使って提供されたスクリプトを実行しています(信頼できるソースですが、私のコントロールではありません)。提供されたスクリプトは、受け取った文脈で私が提供する関数にコールバックする必要があります。nodejs vmスクリプトの関数呼び出しのコンテキストが失われるのを避けるにはどうすればよいですか?

スクリプト内部の機能が期待通りに機能します。しかし、コンテキストで提供された関数が呼び出されると、呼び出されたスクリプトに提供されたコンテキストからの変数はもはやありません。

TEST 
TEST: a=42 
OKFN 
OKFN: a=42 
MYFN 
MYFN: a=42 

ではなく、myfn()の最後はconsole.logはにReferenceErrorを生成します:それは私がの出力を見ることを期待し、実行すると

var vm = require('vm'); 
var sandbox={console:console, myfn:function() { 
     console.log("MYFN"); 
     console.log("MYFN: a="+a); 
}, a:42}; 
var ctx = new vm.createContext(sandbox); 
vm.runInContext("function okfn() { console.log('OKFN'); console.log('OKFN: a='+a); } console.log('TEST'); console.log('TEST: a='+a);okfn(); myfn();", ctx, {filename:"TEST"}); 

:この短いプログラムは、問題を示し、Aがあります定義されていません

runInContext()を介してスクリプトに渡されたコンテキストを、そのスクリプトがコンテキスト自体で提供される関数を呼び出すときに保持する方法はありますか?

答えて

0

関数は、定義されているグローバルスコープにバインドされます。 myfnはメインスクリプトファイルで定義されていたため、そのファイルのグローバルを使用します。その関数を別のグローバルコンテキストにバインドするには、そのコンテキストで再定義/再実行する必要があります。

var vm = require('vm'); 

function myfn() { 
    console.log("MYFN"); 
    console.log("MYFN: a="+ a); 
} 


var sandbox={console:console, a:42}; 
var ctx = new vm.createContext(sandbox); 

// Evaluates the source code of myfn in the new context 
// This will ensure that myfn uses the global context of 'ctx' 
vm.runInContext(myfn.toString(), ctx, {filename: "TEST"}); 

// Retained in the context 
console.log(ctx.myfn); 

// Use it 
vm.runInContext("function okfn() { console.log('OKFN'); console.log('OKFN: a='+a); } console.log('TEST'); console.log('TEST: a='+a);okfn(); myfn();", ctx, {filename:"TEST"}); 
関連する問題