成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

比 Eval 和 Iframe 更強的新一代 JavaScript 沙箱!

開發(fā)
今天我們來看一個進入 statge3 的新的 JavaScript 提案:ShadowRealm API。

今天我們來看一個進入 statge3 的新的 JavaScript 提案:ShadowRealm API。

JavaScript 的運行環(huán)境

領(lǐng)域(realm),這個詞比較抽象,其實就代表了一個 JavaScript 獨立的運行環(huán)境,里面有獨立的變量作用域。

比如下面的代碼:

<body>
<iframe>
</iframe>
<script>
const win = frames[0].window;
console.assert(win.globalThis !== globalThis); // true
console.assert(win.Array !== Array); // true
</script>
</body>

每個 iframe 都有一個獨立的運行環(huán)境,document 的全局對象不同于 iframe 的全局對象,類似的,全局對象上的 Array 肯定也不同。

ShadowRealm API

ShadowRealm API 是一個新的 JavaScript 提案,它允許一個 JS 運行時創(chuàng)建多個高度隔離的 JS 運行環(huán)境(realm),每個 realm 具有獨立的全局對象和內(nèi)建對象。

ShadowRealm 具有下面的類型簽名:

declare class ShadowRealm {
constructor();
evaluate(sourceText: string): PrimitiveValueOrCallable;
importValue(specifier: string, bindingName: string): Promise<PrimitiveValueOrCallable>;
}

每個 ShadowRealm 實例都有自己獨立的運行環(huán)境,它提供了兩種方法讓我們來執(zhí)行運行環(huán)境中的代碼:

  • .evaluate():同步執(zhí)行代碼字符串,類似 eval()。
  • .importValue():返回一個 Promise 對象,異步執(zhí)行代碼字符串。

shadowRealm.evaluate()

.evaluate() 的類型簽名:

evaluate(sourceText: string): PrimitiveValueOrCallable;

.evaluate() 的工作原理很像 eval():

const sr = new ShadowRealm();
console.assert(
sr.evaluate(`'ab' + 'cd'`) === 'abcd'
);

但是與 eval() 不同的是,代碼是在 .evaluate() 的獨立運行環(huán)境中執(zhí)行的:

globalThis.realm = 'incubator realm';

const sr = new ShadowRealm();
sr.evaluate(`globalThis.realm = 'ConardLi realm'`);
console.assert(
sr.evaluate(`globalThis.realm`) === 'ConardLi realm'
);

如果 .evaluate() 返回一個函數(shù),為了方便在外部調(diào)用這個函數(shù)會被包裝,然后在 ShadowRealm 中運行:

globalThis.realm = 'incubator realm';

const sr = new ShadowRealm();
sr.evaluate(`globalThis.realm = 'ConardLi realm'`);

const wrappedFunc = sr.evaluate(`() => globalThis.realm`);
console.assert(wrappedFunc() === 'ConardLi realm');

每當(dāng)一個值傳入 ShadowRealm 時,它必須是原始類型或者可以被調(diào)用的。否則會拋出異常:

> new ShadowRealm().evaluate('[]')
TypeError: value passing between realms must be callable or primitive

shadowRealm.importValue()

.importValue() 的類型簽名:

importValue(specifier: string, bindingName: string): Promise<PrimitiveValueOrCallable>;

你可以直接導(dǎo)入一個外部的模塊,異步執(zhí)行并返回一個 Promise,用法:

// main.js
const sr = new ShadowRealm();
const wrappedSum = await sr.importValue('./my-module.js', 'sum');
console.assert(wrappedSum('hi', ' ', 'folks', '!') === 'hi ConardLi!');

// my-module.js
export function sum(...values) {
return values.reduce((prev, value) => prev + value);
}

與 .evaluate() 一樣,傳入 ShadowRealms 的值(包括參數(shù)和跨環(huán)境函數(shù)調(diào)用的結(jié)果)必須是原始的或可調(diào)用的。

ShadowRealms 可以用來做什么?

  • 在 Web IDE 或 Web 繪圖應(yīng)用等程序中運行插件等第三方代碼。
  • 在 ShadowRealms 中創(chuàng)建一個編程環(huán)境,運行用戶代碼。
  • 服務(wù)器可以在 ShadowRealms 中運行第三方代碼。
  • 在 ShadowRealms 中可以運行測試,這樣外部的JS執(zhí)行環(huán)境不會受到影響,并且每個套件都可以在新環(huán)境中啟動(這有助于提高可復(fù)用性)。
  • 網(wǎng)頁抓取(從網(wǎng)頁中提取數(shù)據(jù))和網(wǎng)頁應(yīng)用測試等可以在 ShadowRealms 中運行。

與其他方案對比

eval()和Function

ShadowRealms 與 eval() 和 Function 很像,但比它們倆都好一點:我們可以創(chuàng)建新的JS運行環(huán)境并在其中執(zhí)行代碼,這可以保護外部的JS運行環(huán)境不受代碼執(zhí)行的操作的影響。

Web Workers

Web Worker 是一個比 ShadowRealms 更強大的隔離機制。其中的代碼運行在獨立的進程中,通信是異步的。

但是,當(dāng)我們想要做一些更輕量級的操作時,ShadowRealms 是一個很好的選擇。它的算法可以同步計算,更便捷,而且全局數(shù)據(jù)管理更自由。

iframe

前面我們已經(jīng)提到了,每個 iframe 都有自己的運行環(huán)境,我們可以在里面同步執(zhí)行代碼。

<body>
<iframe>
</iframe>
<script>
globalThis.realm = 'incubator';
const iframeRealm = frames[0].window;
iframeRealm.globalThis.realm = 'ConardLi';
console.log(iframeRealm.eval('globalThis.realm')); // 'ConardLi'
</script>
</body>

與 ShadowRealms 相比,還是有以下缺點:

  • 只能在瀏覽器中使用 iframe;
  • 需要向 DOM 添加一個 iframe 以對其進行初始化;
  • 每個 iframe 環(huán)境都包含完整的 DOM,這在一些場景下限制了自定義的靈活度;
  • 默認情況下,對象是可以跨環(huán)境的,這意味著需要額外的工作來確保代碼安全。

Node.js 上的 vm 模塊

Node.js 的 vm 模塊與 ShadowRealm API 類似,但具有更多功能:緩存 JavaScript 引擎、攔截 import() 等等。但它唯一的缺點就是不能跨平臺,只能在 Node.js 環(huán)境下使用。

用法示例:在 ShadowRealms 中運行測試

下面我們來看個在 ShadowRealms 中運行測試的小 Demo,測試庫收集通過 test() 指定的測試,并允許我們通過 runTests() 運行它們:

// test-lib.js
const testDescs = [];

export function test(description, callback) {
testDescs.push({description, callback});
}

export function runTests() {
const testResults = [];
for (const testDesc of testDescs) {
try {
testDesc.callback();
testResults.push(`${testDesc.description}: OK\n`);
} catch (err) {
testResults.push(`${testDesc.description}: ${err}\n`);
}
}
return testResults.join('');
}

使用庫來指定測試:

// my-test.js
import {test} from './test-lib.js';
import * as assert from './assertions.js';

test('succeeds', () => {
assert.equal(3, 3);
});

test('fails', () => {
assert.equal(1, 3);
});

export default true;

在下一個示例中,我們動態(tài)加載 my-test.js 模塊來收集然后運行測試。

唉,目前還沒有辦法在不導(dǎo)入任何東西的情況下加載模塊。

這就是為什么在前面示例的最后一行中有一個默認導(dǎo)出。我們使用 ShadowRealm .importvalue() 方法導(dǎo)入 default export 。

// test-runner.js
async function runTestModule(moduleSpecifier) {
const sr = new ShadowRealm();
await sr.importValue(moduleSpecifier, 'default');
const runTests = await sr.importValue('./test-lib.js', 'runTests');
const result = runTests();
console.log(result);
}
await runTestModule('./my-test.js');

在 ShadowRealms 中運行 Web 應(yīng)用

jsdom 庫創(chuàng)建了一個封裝的瀏覽器環(huán)境,可以用來測試 Web 應(yīng)用、從 HTML 中提取數(shù)據(jù)等。它目前使用的是 Node.js vm 模塊,未來可能會更新為使用 ShadowRealms(后者的好處是可以跨平臺,而 vm 目前只支持 Node.js)。

責(zé)任編輯:趙寧寧 來源: code秘密花園
相關(guān)推薦

2014-10-13 14:25:35

葡萄城JavaScriptWijmo 5

2010-02-07 15:50:33

Android手機

2009-09-02 16:10:40

ADSL技術(shù)

2013-01-04 16:15:08

微軟ERPDynamics AX

2012-07-02 10:36:19

菲亞特

2022-03-10 16:01:29

Playwright開源

2021-12-16 12:42:18

AIoT人工智能物聯(lián)網(wǎng)

2016-01-26 11:58:12

2012-07-25 13:19:16

ibmdw

2024-01-23 12:27:15

2010-12-14 12:48:43

SafeNetPKI應(yīng)用程序虛擬環(huán)境

2025-04-11 10:00:52

2016-12-11 10:35:52

2013-09-24 10:38:23

2021-07-15 11:16:31

Spring WebWebFlux架構(gòu)

2009-10-13 10:04:51

醫(yī)院協(xié)同呼叫中心

2025-03-17 10:38:30

2011-03-31 17:49:51

微軟嵌入式WindowsEmbe

2018-06-01 15:18:43

LinuxOrbital App開源

2009-03-11 13:02:20

存儲虛擬化數(shù)據(jù)中心
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩精品福利 | 精品综合久久久 | 免费黄色网址视频 | 成人在线视频网址 | 激情五月综合 | 最新中文在线视频 | 欧美日韩精品免费观看 | 久操亚洲 | 成人av免费网站 | 毛片网在线观看 | 国产精品一区二区三区四区 | 欧美精品一区二区三区蜜桃视频 | 国产一区二区三区久久久久久久久 | 亚洲精品www | 国产99精品 | 成年女人免费v片 | 亚洲精品无人区 | 国产欧美日韩一区二区三区在线 | 中文字幕亚洲视频 | 欧美性受xxx | 在线成人免费观看 | 日韩在线欧美 | 狠狠色综合久久丁香婷婷 | 成人亚洲 | 91电影在线播放 | 午夜免费电影 | 午夜激情免费视频 | 亚洲一区在线播放 | 色婷婷亚洲一区二区三区 | 午夜视频在线播放 | 欧美日韩高清一区 | 久久伊人免费视频 | 国产 日韩 欧美 在线 | 黄色三级免费网站 | 日韩在线视频一区 | 国产精品久久久久久久久久久免费看 | 日韩有码在线观看 | 波多野结衣电影一区 | 精品视频一区二区三区在线观看 | 欧美日韩视频在线 | 日韩一区二区在线观看视频 |