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 ストレージ パス設定操作
コンピュータ システムが再インストールされ、侵入テスト学習環境 DVWA を再インストールする必要が...
HTML コード内の連続するスペースまたは空白行 (改行) はすべて 1 つのスペースとして表示され...
1. コマンド mysqld --skip-grant-tables を入力します (前提条件: m...
右クリックメニューを無効にする <body oncontextmenu=self.event....
以下の例では、名前が入っている td の幅が 60px のとき、2 行目の文字数が少ない場合は正常に...
目次1. インデックスの役割2. インデックスの作成と削除(1)ALTER TABLE文を使用して、...
フォーム内のフォーム フィールドが無効に設定されている場合、フォーム フィールドの値は送信されません...
ステップ1: Stowをインストールするこの例では CentOS を使用しているため、拡張 EPEL...
この記事で説明する等幅レイアウトでは、純粋な CSS を使用して、要素の幅を手動で設定することなく、...
ウェブサイトのフロントエンド開発で発生するセキュリティ問題は、クライアントブラウザで実行されるコード...
この記事では、Linux ファイル管理コマンドについて例を挙げて説明します。ご参考までに、詳細は以下...
成果を達成する実装のアイデアフィルターのコントラストとぼかしを利用して溶ける効果を実現します。親要素...
目次原理ソースコード分析委任されたイベントバインディングすべてのサポートされているイベントを聴くネイ...
目次1. ユーザーを追加する2. ユーザー名とホストを変更する3. パスワードを変更する4. ユーザ...
IE で ClearType をオンにした後に発生する透明フォントの問題を解決するには、透明要素に背...