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])
说明:
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
vm.iscontext(sandbox)
说明:
当给定的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
vm.runincontext(code, contextifiedsandbox[, options])
说明:
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(code)(已废弃)
说明:
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'
vm.runinnewcontext(code[, sandbox][, options])
说明:
首先给指定的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(code[, options])
说明:
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类型的实例包含若干预编译的脚本,这些脚本能够在特定的沙箱(或者上下文)中被运行。
new vm.script(code, options)
说明:
创建一个新的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' }
script.runincontext(contextifiedsandbox[, options])
说明:
在指定的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' }
script.runinnewcontext([sandbox[, options]])
说明:
首先给指定的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' }]
script.runinthiscontext([options])
说明:
在指定的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
例子:在vm中运行一个http server
'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程序设计有所帮助。
推荐阅读
-
Python3.5 Pandas模块之DataFrame用法实例分析
-
Python3.5 Pandas模块之Series用法实例分析
-
Node.js JSON模块用法实例分析
-
Python3.5内置模块之time与datetime模块用法实例分析
-
Python3.5内置模块之os模块、sys模块、shutil模块用法实例分析
-
Node.js API详解之 tty功能与用法实例分析
-
Python3.5内置模块之random模块用法实例分析
-
Node.js API详解之 dgram模块用法实例分析
-
Node.js API详解之 V8模块用法实例分析
-
Node.js API详解之 console模块用法详解