[英]Altering Global Scope for dynamically loaded module in Node.js
從源動態加載模塊:
var src="HERE GOES MY SOURCE"
var Module = module.constructor;
var m = new Module();
m._compile(src, 'a-path-that-does-not-exist');
需要達到以下幾點:
所有,我能想到的是將腳本包裝在它自己的 function 中,就像 nodejs 已經為 commonJS 模塊所做的那樣。 這是常規包裝。
(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});
如果您使用自己的包裝器包裝該用戶代碼,然后當您調用它來執行它時,您可以為require
、 module
和任何其他半全局符號定義自己的值。
如果你也把'use strict'; 作為包裝器 function 的第一行(在任何用戶代碼之前),那么這將消除對global
object 的默認分配,僅使用x = 4
之類的東西,因為如果沒有先明確定義x
將是一個錯誤。 如果您隨后還創建自己的全局 object 並將其作為參數傳遞,則可以防止任何人分配給真正的全局 object。 我認為您不能阻止對預先存在的全局變量的隱式讀取訪問。
因此,您的包裝器可能如下所示:
(function(exports, require, module, __filename, __dirname, global) {
'use strict';
// insert user code here before evaluating it with eval()
// and getting the function which you can then call and pass the desired arguments
});
然后,當您調用此 function 時,您將所有 arguments 的值(不是真實值)傳遞給它。
請注意,很難說這種方案的防漏性能到底如何。 任何真正的安全都應該在資源受限的虛擬機中運行。
另一個想法,您可以在具有自己的原始全局變量集的工作線程中運行。 因此,您執行上述所有操作並在工作線程中運行它。
在評論中解決您的問題:
是否“使用嚴格”; 需要 go 在包裝器 function 內部還是外部?
它必須是包裝器 function 中的第一行代碼,就在您插入用戶代碼的位置之前。 這個想法是強制 function scope(用戶代碼所在的位置)在該包裝器中處於嚴格模式,以限制它可以做的一些事情。
你能解釋一下“我認為你不能阻止對預先存在的全局變量的隱式讀取訪問。”嗎? 如果我提供自己的 object 作為全局變量,內部腳本如何訪問預先存在的全局變量?
任何代碼,甚至是嚴格模式代碼都可以在沒有global
前綴的情況下訪問預先存在的全局變量。 雖然您可以通過在包裝器 function arguments 並通過強制它進入嚴格模式來阻止代碼創建新的global
變量,但您不能阻止嚴格模式代碼讀取現有的全局變量,因為它們可以在沒有全局變量的情況下這樣做字首。 因此,如果有一個預先存在的名為“foo”的全局變量,那么現有代碼可以像這樣引用它:
console.log(foo);
或者
foo = 12;
如果在更近的 scope 中沒有foo
,解釋器將在全局 object 上找到foo
並使用它。
請注意,嚴格模式會阻止自動創建新的全局,例如:
greeting = "happy birthday"
您能否詳細說明沒有“資源受限的虛擬機”?
我說的是真正的硬件/操作系統級別的虛擬機,它們允許您完全控制進程可能使用的資源(磁盤訪問、sockets、memory、硬件等)。 它本質上是一個與同一系統上的任何其他 VM 分開的虛擬計算機環境。 這是一個更嚴格的控制水平。
WorkerThread 是一個非常有趣的概念。 會看嗎? 我的理解是 WorkerThreads 提供 memory 隔離,共享數據的唯一方法是發送消息(有效地創建副本)?
是的,工作線程提供了很好的隔離,因為它們啟動了一個全新的 JS 引擎並擁有自己的全局變量。 它們可以以某種方式共享 ArrayBuffers(如果你選擇這樣做的話),但是普通的 JS 變量不能跨線程邊界訪問。 它們通常會通過消息傳遞(通過事件隊列自動同步)進行通信,但如果需要,您也可以通過 sockets 進行通信。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.