1. シナリオ前回の記事では、Quickjs が JavaScript サンドボックスの詳細をカプセル化し、 2. IJavaScriptShadowboxを実装する実際、Web Worker は 実装は 2 つの部分に分かれており、1 つはメイン スレッドで 2.1 メインスレッドの実装「./IJavaScriptShadowbox」から {IJavaScriptShadowbox} をインポートします。 エクスポートクラス WebWorkerShadowbox は IJavaScriptShadowbox を実装します { 破棄(): void { this.worker.terminate(); } 民間労働者!:労働者; eval(コード: 文字列): void { const blob = new Blob([code], { type: "application/javascript" }); this.worker = 新しいWorker(URL.createObjectURL(blob), { 資格情報: "include", }); this.worker.addEventListener("メッセージ", (ev) => { const msg = ev.data as { チャネル: 文字列; データ: 任意 }; // console.log('msg.data: ', msg) if (!this.listenerMap.has(msg.channel)) { 戻る; } this.listenerMap.get(msg.channel)!.forEach((handle) => { ハンドル(msg.data); }); }); } プライベート読み取り専用リスナーマップ = 新しい Map<string, ((data: any) => void)[]>(); 出力(チャンネル: 文字列、データ: 任意): void { this.worker.postMessage({ チャンネル: チャンネル、 データ、 }); } on(チャンネル: 文字列、ハンドル: (データ: 任意) => void): void { if (!this.listenerMap.has(channel)) { this.listenerMap.set(チャンネル、[]); } this.listenerMap.get(チャンネル)!.push(ハンドル); } offByChannel(チャンネル: 文字列): void { this.listenerMap.delete(チャンネル); } } 2.2 Webワーカースレッドの実装「./IEventEmitter」から IEventEmitter をインポートします。 エクスポートクラスWebWorkerEventEmitterはIEventEmitterを実装します{ プライベート読み取り専用リスナーマップ = 新しい Map<string, ((data: any) => void)[]>(); 出力(チャンネル: 文字列、データ: 任意): void { postMessage({ チャンネル: チャンネル、 データ、 }); } on(チャンネル: 文字列、ハンドル: (データ: 任意) => void): void { if (!this.listenerMap.has(channel)) { this.listenerMap.set(チャンネル、[]); } this.listenerMap.get(チャンネル)!.push(ハンドル); } offByChannel(チャンネル: 文字列): void { this.listenerMap.delete(チャンネル); } 初期化() { onmessage = (ev) => { const msg = ev.data as { チャネル: 文字列; データ: 任意 }; if (!this.listenerMap.has(msg.channel)) { 戻る; } this.listenerMap.get(msg.channel)!.forEach((handle) => { ハンドル(msg.data); }); }; } 破壊する() { このリスナーマップをクリアします。 onmessage = null; } } 3. WebWorkerShadowbox/WebWorkerEventEmitterを使用するメインスレッドコード const シャドウボックス: IJavaScriptShadowbox = new WebWorkerShadowbox(); shadowbox.on("hello", (名前: 文字列) => { console.log(`hello ${name}`); }); // ここでのコードは、shadowbox.eval(code); の下の Web ワーカー スレッドのコードを参照します。 shadowbox.emit("open"); Web ワーカー スレッド コード const em = 新しい WebWorkerEventEmitter(); em.on("open", () => em.emit("hello", "liuli")); 以下はコード実行フローの概略図です。Web 4. WebワーカーのグローバルAPIを制限する
実際、 // ホワイトリストWorkerGlobalScope.ts /** * Webワーカーランタイムのホワイトリストを設定して、安全でないAPIをすべて禁止する */ エクスポート関数 whitelistWorkerGlobalScope(list: PropertyKey[]) { const ホワイトリスト = 新しい Set(リスト); const all = Reflect.ownKeys(globalThis); すべて.forEach((k) => { if (ホワイトリスト.has(k)) { 戻る; } if (k === "ウィンドウ") { console.log("ウィンドウ: ", k); } Reflect.deleteProperty(globalThis, k); }); } /** * グローバル値のホワイトリスト */ 定数ホワイトリスト: ( | キーof タイプof グローバル | WindowOrWorkerGlobalScope のキー | 「コンソール」 )[] = [ "グローバルこれ", "コンソール"、 "タイムアウトの設定", 「タイムアウトをクリア」、 "setInterval"、 「クリア間隔」、 「ポストメッセージ」、 "オンメッセージ", "反映する"、 "配列"、 "地図"、 "セット"、 "関数"、 "物体"、 「ブール値」、 "弦"、 "番号"、 "数学"、 "日付"、 「JSON」、 ]; ホワイトリストWorkerGlobalScope(ホワイトリスト); 次に、サードパーティのコードを実行する前に上記のコードを実行します。 「./whitelistWorkerGlobalScope.js?raw」からbeforeCodeをインポートします。 エクスポートクラス WebWorkerShadowbox は IJavaScriptShadowbox を実装します { 破棄(): void { this.worker.terminate(); } 民間労働者!:労働者; eval(コード: 文字列): void { // この行がキーです const blob = new Blob([beforeCode + "\n" + code], { タイプ: "application/javascript", }); // その他のコード。 。 。 } } ソース コードの記述には ts を使用するため、 ts を 「vite」からdefineConfigとPluginをインポートします。 「@vitejs/plugin-react-refresh」から reactRefresh をインポートします。 「vite-plugin-checker」からチェッカーをインポートします。 「esbuild」から{build}をインポートします。 "path" から * をパスとしてインポートします。 エクスポート関数buildScript(scriptList: string[]): プラグイン{ _scriptList を scriptList.map((src) => path.resolve(src)); 非同期関数buildScript(src: 文字列) { ビルドを待つ({ エントリポイント: [src], 出力ファイル: src.slice(0, src.length - 2) + "js", フォーマット: "iife", バンドル: true、 プラットフォーム:「ブラウザ」、 ソースマップ: "インライン", 上書きを許可する: true、 }); console.log("ビルドが完了しました: ", path.relative(path.resolve(), src)); } 戻る { 名前: "vite-plugin-build-script", 非同期configureServer(サーバー) { server.watcher.add(_scriptList); _scriptList を新しい Set に追加します。 server.watcher.on("change", (filePath) => { // console.log('変更: ', ファイルパス) スクリプトセットにファイルパスがある場合 ビルドスクリプト(ファイルパス); } }); }, 非同期ビルド開始() { // console.log('buildStart: ', this.meta.watchMode) if (this.meta.watchMode) { _scriptList.forEach((src) => this.addWatchFile(src)); } Promise.all(_scriptList.map(buildScript)) を待機します。 }, }; } // https://vitejs.dev/config/ デフォルトのdefineConfigをエクスポートする({ プラグイン: [ 反応リフレッシュ()、 チェッカー({typescript: true})、 ビルドスクリプト([path.resolve("src/utils/app/whitelistWorkerGlobalScope.ts")]), ]、 }); これで、 5. Webワーカーサンドボックスの主な利点
WebWorker カプセル化 JavaScript サンドボックスの詳細に関するこの記事はこれで終わりです。WebWorker カプセル化 JavaScript サンドボックスに関する関連コンテンツの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Docker の Windows ストレージ パス設定操作
1: readonly は、このコントロールをロックして、インターフェイス上で変更できないようにしま...
まずは適用方法を説明します。nginxモジュールにはjtxyとjtcmdの2つがあります。 http...
序文プロジェクトの要件は、ユーザーの現在の位置が特定の地理的位置範囲内にあるかどうかを判断することで...
1. オブジェクト指向のクラス継承これまでの章では、JavaScript のオブジェクト モデルがプ...
目次トピック分析する使用目的解決:コードは次のように実装されます。分析:配列とポインタ解決:コードは...
テーブルに table-layer:fixed スタイルを設定し、テーブル内の行が結合されていること...
序文会社の業務上のニーズにより、独自の MongoDB サービスを構築する予定です。MongoDB ...
目次1. LAN内のプロキシ2. イントラネットの浸透イントラネット侵入とは何ですか?橋プロキシサー...
まず、VMware 14のアクティベーションコードをお渡ししますFF31K-AHZD1-H8ETZ-...
MySQL インストーラーは、MySQL ソフトウェアのあらゆるニーズに対応する、使いやすいウィザー...
方法 1: hostnamectl の変更ステップ1 ホスト名を確認するホスト名ステップ2 ホスト名...
導入アニメーションを使用すると、JavaScript や jQuery に依存せずに、純粋な CSS...
効果:スライドショーが一方向に動く場合、各画像のサイズ、位置、透明度、レベルを変更する必要があります...
1. 配列のよく使われる高階関数配列があり、その配列に対して次の操作を実行したいとします。 100 ...
この記事では、例を使用して、MySQL で複数テーブルの関連統計を実装する方法について説明します。ご...