穩定性: 3 - 穩定
可以通過以下方法訪問該模塊:
var vm = require('vm');
JavaScript 可以立即編譯立即執行,也可以編譯,保存,之后再運行。
vm.runInThisContext()
對 參數code
編譯,運行并返回結果。 運行的代碼沒有權限訪問本地作用域(local scope),但是可以訪問全局對象。
使用 vm.runInThisContext
和 eval
方法運行同樣代碼的例子:
var localVar = 'initial value';
var vmResult = vm.runInThisContext('localVar = "vm";');
console.log('vmResult: ', vmResult);
console.log('localVar: ', localVar);
var evalResult = eval('localVar = "eval";');
console.log('evalResult: ', evalResult);
console.log('localVar: ', localVar);
// vmResult: 'vm', localVar: 'initial value'
// evalResult: 'eval', localVar: 'eval'
vm.runInThisContext
沒有訪問本地作用域,所以沒有改變 localVar
。 eval
范圍了本地作用域,所以改變了 localVar
。
vm.runInThisContext
用起來很像間接調用 eval
,比如 (0,eval)('code')
。但是,vm.runInThisContext
也包含以下選項:
filename
: 允許更改顯示在站追蹤(stack traces)的文件名。displayErrors
: 是否在 stderr 上打印錯誤,拋出異常的代碼行高亮顯示。會捕獲編譯時的語法錯誤,和執行時拋出的錯誤。默認為 true
。timeout
: 中斷前代碼執行的毫秒數。如果執行終止,將會拋出錯誤。如果參數 sandbox
不為空,調用 vm.runInContext
或 script.runInContext
時可以調用沙箱的上下文。以此方式運行的腳本,sandbox
是全局對象,它保留自己的屬性同時擁有標準全局對象(global object)擁有的內置對象和函數。
如果參數 sandbox 對象為空,返回一個可用的新且空的上下文相關的沙盒對象。
這個函數對于創建一個可運行多腳本的沙盒非常有用。比如,在模擬瀏覽器的時候可以使用該函數創建一個用于表示 window 全局對象的沙箱,并將所有 <script>
標簽放入沙箱執行。
沙箱對象是否已經通過調用 vm.createContext
上下文化。
vm.runInContext
編譯代碼,運行在 contextifiedSandbox
并返回結果。運行代碼不能訪問本地域。contextifiedSandbox
對象必須通過 vm.createContext
上下文化;code
會通過全局變量使用它。
vm.runInContext
和 vm.runInThisContext
參數相同。
在同一個上下文中編譯并執行不同的腳本,例子:
var util = require('util');
var vm = require('vm');
var sandbox = { globalVar: 1 };
vm.createContext(sandbox);
for (var i = 0; i < 10; ++i) {
vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));
// { globalVar: 1024 }
注意,執行不被信任的代碼是需要技巧且要非常的小心。vm.runInContext
非常有用,不過想要安全些,最好還是在獨立的進程里運行不被信任的代碼。
vm.runInNewContext
編譯代碼, 如果提供了 sandbox ,則將 sandbox 上下文化,否則創建一個新的上下文化過的沙盒,將沙盒作為全局變量運行代碼并返回結果。
vm.runInNewContext
和 vm.runInThisContext
參數相同。
編譯并執行代碼,增加全局變量值,并設置一個新的。這些全局變量包含在一個新的沙盒里。
var util = require('util');
var vm = require('vm'),
var sandbox = {
animal: 'cat',
count: 2
};
vm.runInNewContext('count += 1; name = "kitty"', sandbox);
console.log(util.inspect(sandbox));
// { animal: 'cat', count: 3, name: 'kitty' }
注意,執行不被信任的代碼是需要技巧且要非常的小心。vm.runInNewContext
非常有用,不過想要安全些,最好還是在獨立的進程里運行不被信任的代碼。
vm.runInDebugContext
在 V8 的調試上下文中編譯并執行。最主要的應用場景是獲得 V8 調試對象訪問權限。
var Debug = vm.runInDebugContext('Debug');
Debug.scripts().forEach(function(script) { console.log(script.name); });
注意,調試上下文和對象內部綁定到 V8 的調試實現里,并可能在沒有警告時改變(或移除)。
可以通過 --expose_debug_as=
開關暴露調試對象。
包含預編譯腳本的類,并在指定的沙盒里執行。
創建一個新的腳本編譯代碼,但是不運行。使用被創建的 vm.Script
來表示編譯完的代碼。這個代碼可以使用以下的方法調用多次。返回的腳本沒有綁定到任何全局變量。在運行前綁定,執行后釋放。
創建腳本的選項有:
filename
: 允許更改顯示在站追蹤(stack traces)的文件名。displayErrors
: 是否在 stderr 上打印錯誤,拋出異常的代碼行高亮顯示。只會捕獲編譯時的語法錯誤,執行時拋出的錯誤由腳本的方法的選項來控制。默認為 true
。和 vm.runInThisContext
類似,只是作為 Script
腳本對象的預編譯方法。script.runInThisContext
執行編譯過的腳本并返回結果。被運行的代碼沒有本地作用域訪問權限,但是擁有權限訪問全局對象。
以下例子,使用 script.runInThisContext
編譯代碼一次,并運行多次:
var vm = require('vm');
global.globalVar = 0;
var script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
for (var i = 0; i < 1000; ++i) {
script.runInThisContext();
}
console.log(globalVar);
// 1000
所運行的代碼選項:
displayErrors
: 是否在 stderr 上打印錯誤,拋出異常的代碼行高亮顯示。僅適用于執行時拋出的錯誤。不能創建一個語法錯誤的 Script
實例,因為構造函數會拋出。timeout
: 中斷前代碼執行的毫秒數。如果執行終止,將會拋出錯誤。和 vm.runInContext
類似,只是作為預編譯的 Script
對象方法。script.runInContext
運行腳本(在 contextifiedSandbox
中編譯)并返回結果。運行的代碼沒有權限訪問本地域。
script.runInContext
的選項和 script.runInThisContext
類似。
例子: 編譯一段代碼,并執行多次,這段代碼實現了一個全局變量的自增,并創建一個新的全局變量。這些全局變量保存在沙盒里。
var util = require('util');
var vm = require('vm');
var sandbox = {
animal: 'cat',
count: 2
};
var script = new vm.Script('count += 1; name = "kitty"');
for (var i = 0; i < 10; ++i) {
script.runInContext(sandbox);
}
console.log(util.inspect(sandbox));
// { animal: 'cat', count: 12, name: 'kitty' }
注意,執行不被信任的代碼是需要技巧且要非常的小心。script.runInContext
非常有用,不過想要安全些,最好還是在獨立的進程里運行不被信任的代碼。
和 vm.runInNewContext
類似,只是作為預編譯的 Script
對象方法。 若提供 sandbox 則 script.runInNewContext 將 sandbox 上下文化,若未提供,則創建一個新的上下文化的沙箱。
script.runInNewContext
和 script.runInThisContext
的參數類似。
例子: 編譯代碼(設置了一個全局變量)并在不同的上下文里執行多次。這些全局變量會被保存在沙箱中。
var util = require('util');
var vm = require('vm');
var sandboxes = [{}, {}, {}];
var script = new vm.Script('globalVar = "set"');
sandboxes.forEach(function (sandbox) {
script.runInNewContext(sandbox);
});
console.log(util.inspect(sandboxes));
// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
注意,執行不被信任的代碼是需要技巧且要非常的小心。script.runInNewContext
非常有用,不過想要安全些,最好還是在獨立的進程里運行不被信任的代碼。