你好,
我试图弄清楚为什么内置模块是从主机代理的,而在 vm 中不需要。
这是我目前的设置:
const vm = new NodeVM({
require: {
external: true,
context: 'sandbox',
builtin: ['*'],
},
});
vm.run(...);
在VM内部,我需要一个外部模块( axios
如果重要的话)并且在依赖链中它需要另一个模块( follow-redirects
)来执行此操作(或多或少):
var Writable = require('stream').Writable;
function RedirectableRequest(options, responseCallback) {
// .....
}
RedirectableRequest.prototype = Object.create(Writable.prototype);
RedirectableRequest.prototype._performRequest = function () { // <-------- this line breaks
// ..........
}
在 vm 中运行此代码会引发:TypeError:代理上的“设置”:陷阱为属性“_performRequest”返回错误。
流对象被代理到 vm。
当虚拟机内部实际需要stream
时运行此代码(通过在此处删除 if 语句:https://github.com/patriksimek/vm2/blob/master/lib/sandbox.js#L133)是在职的。
在 osx 上运行节点 6.10.3。
谢谢
与#127相关
我继续将 if 语句更改为:
if( vm.options.require.context === 'sandbox' && modulename !== 'async_hooks' ){
我发现在节点 8.x 中我遇到了 async_hooks 的问题
我还找到了另一种解决方案(我认为更适合范式)。
基本上,我发现上下文代码试图写入它在其上下文中创建的对象的原型,但它扩展了从另一个上下文引入的对象。
根据设置代理处理程序的文档,如果您尝试设置的对象上不存在该属性,则将调用原型设置处理程序。
所以;
目的
原型
a <-设置这个(原型上实际上不存在)
__proto__ (代理)
set: (){} <- 实际上调用这个
当调用 set 处理程序时,receiver 参数将被设置为我们试图设置的原始对象。 我的解决方案是这样的:
--- a/node_modules/vm2/lib/contextify.js
+++ b/node_modules/vm2/lib/contextify.js
@@ -17,7 +17,23 @@ const DEBUG = false;
const OPNA = 'Operation not allowed on contextified object.';
const ERROR_CST = Error.captureStackTrace;
const FROZEN_TRAPS = {
- set: (target, key) => false,
+ set: (target, key, value, receiver) => {
+ if( target !== receiver ){
+
+ Object.defineProperty(receiver, key, {
+ value: value,
+ writable: true,
+ enumerable: true,
+ configurable: true
+ })
+
+ return true;
+
+ }
+
+ return false;
+
+ },
什么状态? 项目死了?
此问题已自动标记为过时,因为它最近没有活动。 如果没有进一步的活动,它将被关闭。 感谢你的贡献。
最有用的评论
我还找到了另一种解决方案(我认为更适合范式)。
基本上,我发现上下文代码试图写入它在其上下文中创建的对象的原型,但它扩展了从另一个上下文引入的对象。
根据设置代理处理程序的文档,如果您尝试设置的对象上不存在该属性,则将调用原型设置处理程序。
所以;
目的
原型
a <-设置这个(原型上实际上不存在)
__proto__ (代理)
set: (){} <- 实际上调用这个
当调用 set 处理程序时,receiver 参数将被设置为我们试图设置的原始对象。 我的解决方案是这样的: