您好,登錄后才能下訂單哦!
小編這次要給大家分享的是Node.js API中vm模塊用法實例詳解,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
本文實例講述了Node.js API詳解之 vm模塊用法。分享給大家供大家參考,具體如下:
Node.js API詳解之 vm
vm 模塊提供了一系列 API 用于在 V8 虛擬機環境中編譯和運行代碼。
JavaScript 代碼可以被編譯并立即運行,或編譯、保存然后再運行。
常見的用法是在沙盒中運行代碼。沙盒代碼使用不同的V8上下文。
const vm = require('vm'); const x = 1; const sandbox = { x: 2 }; vm.createContext(sandbox); // Contextify the sandbox. const code = 'x += 40; var y = 17;'; // x and y are global variables in the sandboxed environment. // Initially, x has the value 2 because that is the value of sandbox.x. vm.runInContext(code, sandbox); console.log(sandbox.x); // 42 console.log(sandbox.y); // 17 console.log(x); // 1; y is not defined.
注意: vm模塊并不是實現代碼安全性的一套機制。 絕不要試圖用其運行未經信任的代碼.
說明:
vm.createContext()主要是用于創建一個能運行多個腳本的sandbox。
比如說,在模擬一個網頁瀏覽器時,此方法可以被用于創建一個單獨的sandbox來代表一個窗口的全局對象,然后所有的script標簽都可以在這個sandbox的上下文中運行。
給定一個sandbox對象, vm.createContext()會設置此sandbox,
從而讓它具備在vm.runInContext()或者script.runInContext()中被使用的能力。
如果未提供sandbox(或者傳入undefined),那么會返回一個全新的,空的,上下文隔離化后的sandbox對象。
對于此方法中所調用的腳本,他們的全局對象不僅擁有我們提供的sandbox對象的所有屬性,同時還有任何global object所擁有的屬性。
對于這些腳本之外的所有代碼,他們的全局變量將保持不變。
demo:
const util = require('util'); const vm = require('vm'); global.globalVar = 3; const sandbox = { globalVar: 1 }; vm.createContext(sandbox); vm.runInContext('globalVar *= 2;', sandbox); console.log(util.inspect(sandbox)); // { globalVar: 2 } console.log(util.inspect(globalVar)); // 3
說明:
當給定的sandbox對象已經被vm.createContext()上下文隔離化,則返回真。
demo:
const util = require('util'); const vm = require('vm'); global.globalVar = 3; const sandbox = { globalVar: 1 }; vm.createContext(sandbox); console.log(vm.isContext(sandbox)); // true
說明:
code:將被編譯和運行的JavaScript代碼
contextifiedSandbox:一個被上下文隔離化過的對象,會在代碼被編譯和執行之后充當global對象
options:
filename:定義供腳本生成的堆棧跟蹤信息所使用的文件名
lineOffset:定義腳本生成的堆棧跟蹤信息所顯示的行號偏移
columnOffset:定義腳本生成的堆棧跟蹤信息所顯示的列號偏移
displayErrors:當值為真的時候,假如在解析代碼的時候發生錯誤Error,引起錯誤的行將會被加入堆棧跟蹤信息
timeout:定義在被終止執行之前此code被允許執行的最大毫秒數。假如執行被終止,將會拋出一個錯誤Error
vm.runInContext()在指定的contextifiedSandbox的上下文里執行vm.Script對象中被編譯后的代碼并返回其結果。
被執行的代碼無法獲取本地作用域。contextifiedSandbox必須是事先被vm.createContext()上下文隔離化過的對象。
demo:
const util = require('util'); const vm = require('vm'); global.globalVar = 3; const sandbox = { globalVar: 1 }; vm.createContext(sandbox); vm.runInContext('globalVar *= 2;', sandbox); console.log(util.inspect(sandbox)); // { globalVar: 2 }
說明:
vm.runInDebugContext()會在V8的調試上下文中編譯并執行code。此方法主要在需要獲取V8Debug對象的時候使用。
注意: 調試上下文和對象從本質而言是從屬于V8調試器的,故有可能會在沒有事先警告的情況下被改變(甚至被移除)
Debug對象另外還可以通過特定于V8的–expose_debug_as命令行選項獲得。
demo:
const vm = require('vm') const Debug = vm.runInDebugContext('Debug'); console.log(Debug.findScript(process.emit).name); // 'events.js' console.log(Debug.findScript(process.exit).name); // 'internal/process.js'
說明:
首先給指定的sandbox(若為undefined,則會新建一個sandbox)提供一個隔離的上下文,
再在此上下文中執行vm.Script中被編譯的代碼,最后返回結果。運行中的代碼無法獲取本地作用域。
demo:
const util = require('util'); const vm = require('vm'); const sandbox = { animal: 'cat', count: 2 }; vm.runInNewContext('count += 1; name = "kitty"', sandbox); console.log(util.inspect(sandbox)); // { animal: 'cat', count: 3, name: 'kitty' }
說明:
vm.runInThisContext()在當前的global對象的上下文中編譯并執行code,最后返回結果。
運行中的代碼無法獲取本地作用域,但可以獲取當前的global對象。
demo:
const vm = require('vm'); let localVar = 'initial value'; const vmResult = vm.runInThisContext('localVar = "vm";'); console.log('vmResult:', vmResult); console.log('localVar:', localVar); const evalResult = eval('localVar = "eval";'); console.log('evalResult:', evalResult); console.log('localVar:', localVar); // vmResult: 'vm', localVar: 'initial value' // evalResult: 'eval', localVar: 'eval'
說明:
vm.Script類型的實例包含若干預編譯的腳本,這些腳本能夠在特定的沙箱(或者上下文)中被運行。
說明:
創建一個新的vm.Script對象只編譯代碼但不會執行它。編譯過的vm.Script此后可以被多次執行。
值得注意的是,code是不綁定于任何全局對象的,相反,它僅僅綁定于每次執行它的對象。
code:要被解析的JavaScript代碼
options:
filename:定義供腳本生成的堆棧跟蹤信息所使用的文件名
lineOffset:定義腳本生成的堆棧跟蹤信息所顯示的行號偏移
columnOffset:定義腳本生成的堆棧跟蹤信息所顯示的列號偏移
displayErrors:當值為真的時候,假如在解析代碼的時候發生錯誤Error,引起錯誤的行將會被加入堆棧跟蹤信息
timeout:定義在被終止執行之前此code被允許執行的最大毫秒數。假如執行被終止,將會拋出一個錯誤[Error][]。
cachedData:為源碼提供一個可選的存有v8代碼緩存數據的Buffer。一旦提供了此Buffer,取決于v8引擎對Buffer中數據的接受狀況,cachedDataRejected值將會被設為要么 真要么為假。
produceCachedData:當值為真且cachedData不存在的時候,v8將會試圖為code生成代碼緩存數據。一旦成功,一個有V8代碼緩存數據的Buffer將會被生成和儲存在vm.Script返回的實例的cachedData屬性里。 取決于代碼緩存數據是否被成功生成,cachedDataProduced的值會被設置為true或者false。
demo:
const util = require('util'); const vm = require('vm'); const sandbox = { animal: 'cat', count: 2 }; const script = new vm.Script('count += 1; name = "kitty";'); const context = vm.createContext(sandbox); script.runInContext(context); console.log(util.inspect(sandbox)); // { animal: 'cat', count: 3, name: 'kitty' }
說明:
在指定的contextifiedSandbox中執行vm.Script對象中被編譯后的代碼并返回其結果。
被執行的代碼無法獲取本地作用域。
contextifiedSandbox:由vm.createContext()返回的[contextified][]對象
demo:
const util = require('util'); const vm = require('vm'); const sandbox = { animal: 'cat', count: 2 }; const script = new vm.Script('count += 1; name = "kitty";'); const context = vm.createContext(sandbox); for (let i = 0; i < 10; ++i) { script.runInContext(context); } console.log(util.inspect(sandbox)); // { animal: 'cat', count: 12, name: 'kitty' }
說明:
首先給指定的sandbox提供一個隔離的上下文, 再在此上下文中執行vm.Script中被編譯的代碼,最后返回結果。
運行中的代碼無法獲取本地作用域。
demo:
const util = require('util'); const vm = require('vm'); const script = new vm.Script('globalVar = "set"'); const sandboxes = [{}, {}, {}]; sandboxes.forEach((sandbox) => { script.runInNewContext(sandbox); }); console.log(util.inspect(sandboxes)); // [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
說明:
在指定的global對象的上下文中執行vm.Script對象里被編譯的代碼并返回其結果。
被執行的代碼雖然無法獲取本地作用域,但是能獲取global對象。
demo:
const vm = require('vm'); global.globalVar = 0; const script = new vm.Script('globalVar += 1'); for (let i = 0; i < 1000; ++i) { script.runInThisContext(); } console.log(globalVar); // 1000
'use strict'; const vm = require('vm'); const code = ` (function(require) { const http = require('http'); http.createServer((request, response) => { response.writeHead(200, { 'Content-Type': 'text/plain' }); response.end('Hello World\\n'); }).listen(8124); console.log('Server running at http://127.0.0.1:8124/'); })`; vm.runInThisContext(code)(require);
看完這篇關于Node.js API中vm模塊用法實例詳解的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。