vm
vm是node的一个核心模块,核心功能官方文档介绍是:
The vm module provides APIs for compiling and running code within V8 Virtual Machine contexts. The vm module is not a security mechanism. Do not use it to run untrusted code. The term "sandbox" is used throughout these docs simply to refer to a separate context, and does not confer any security guarantees.
意思就是:vm可以使用v8的Virtual Machine contexts动态地编译和执行代码,而代码的执行上下文是与当前进程隔离的,但是这里的隔离并不是绝对的安全,不完全等同浏览器的沙箱环境。
例子
vm的使用很简单,下面是几个例子:
- vm.runInNewContext
```
const vm = require(‘vm‘);
const sandbox = { a: 1 };
// 在新的上下文运行
const result = vm.runInNewContext(‘a += 1‘, sandbox);
console.log(result);// 2
console.log(sandbox);// { a: 2 }
``` -
vm.runInContext
```
const vm = require(‘vm‘);
const sandbox = { a: 1 };
// https://nodejs.org/api/vm.html#vm_what_does_it_mean_to_contextify_an_object
vm.createContext(sandbox);
// 在执行上下文运行
const result = vm.runInContext(‘a += 1‘, sandbox);
console.log(result);// 2
console.log(sandbox);// { a: 2 }
``` -
vm.runInThisContext
```
const vm = require(‘vm‘);
global.a = 1;
// 在当前上下文运行
vm.runInThisContext(‘a += 1‘);
console.log(global.a);// 2
```
使用场景
我个人理解vm的使用场景有2个:
- 环境隔离:
因为node的js代码是单线程,在并发的场景下,需要考虑上下文的竞争和互相影响,直接使用vm,可以最小成本的解决这个问题。vue ssr在2.3.0以前,就是用vm来做隔离的渲染的,但是也带来了性能的问题,具体可以查看文档的介绍。
- 动态执行字符串代码:
这在某些需求场景下只能使用vm。
劣势
vm也有明显的劣势:
- 耗费资源:
这里有文章比较eval
和vm
的性能:https://odino.org/eval-no-more-understanding-vm-vm2-nodejs/。(当然eval的安全问题更大,这是另外的话题)。 - maybe attacked
vm也存在安全问题,对于执行外部的代码,可能引发安全问题。所以有个开源库专门解决了这个问题,https://github.com/patriksimek/vm2,声明已经过滤了所有已知攻击。
来源:https://segmentfault.com/a/1190000017210397
原文地址:https://www.cnblogs.com/thatme/p/10162262.html