不必使用 iframe 和 eval,JavaScript 新一代隔離沙箱!
我們經常需要處理來自不同來源的代碼,無論是第三方的廣告、分析腳本、用戶自定義插件,還是動態加載的模塊,將這些不受信任或半信任的代碼集成到我們的應用中時,總會伴隨著巨大的風險。
為了解決這些問題,開發者們曾嘗試過各種方法,如 iframe、Web Workers,甚至是危險的 eval。但它們各有缺點:iframe 過于笨重,通信復雜;Web Workers 是異步的,不適合需要同步執行的場景;eval 則完全沒有隔離性。

什么是 ShadowRealm?
ShadowRealm 是一個正在制定的 ECMAScript 標準,它允許開發者創建一個全新的、被隔離的 JavaScript 全局環境(Global Environment)。
我們可以把它想象成一個輕量級的、純粹為 JavaScript 準備的 iframe,但它沒有 DOM、沒有渲染開銷,并且能夠以一種可控的方式進行同步通信。
每個 ShadowRealm 實例都擁有自己獨立的全局對象(globalThis)和一套完整的內建 JavaScript 對象(如 Object, Array, Promise 等)。在其中執行的代碼無法訪問主頁面的 window 或 document,從而實現了強大的安全隔離。
核心概念與 API 用法
ShadowRealm 的 API 設計得非常簡潔。主要包含以下幾個部分:
(1) 創建 Realm
通過 new ShadowRealm() 構造函數可以輕松創建一個新的 Realm。
// 在主環境中
const realm = new ShadowRealm();(2) 執行代碼
使用 evaluate() 方法可以在 Realm 內部執行一段 JavaScript 代碼字符串。這段代碼會返回一個 Promise,解析后的值是代碼的最終執行結果。

注意:evaluate 內部的代碼無法訪問外部作用域的任何變量。
(3) 導入函數
evaluate() 很有用,但更強大的功能是與 Realm 內部的函數進行交互。importValue() 方法允許我們從 Realm 內部導入一個函數,以便在主環境中調用它。
// `greet` 是在上面 evaluate 中定義的函數
const wrappedGreet = await realm.importValue(
// 'greet' 是 Realm 中全局可用的函數名
'greet'
);
// 調用這個“包裝后”的函數
const message = await wrappedGreet('World');
console.log(message); // 輸出: "Hello from the Realm, World!"截至目前,ShadowRealm API 處于 TC39 流程的 Stage 3,意味著其設計已經穩定,只待瀏覽器廠商廣泛實現和最終批準。
























