1. Szenario Im vorherigen Artikel „Quickjs kapselt JavaScript-Sandbox-Details ein“, wurde eine Sandbox basierend auf 2. Implementieren Sie IJavaScriptShadowbox Tatsächlich stellt Web Worker eine Die Implementierung ist in zwei Teile unterteilt: Einer besteht darin, 2.1 Implementierung des Hauptthreadsimportiere { IJavaScriptShadowbox } aus "./IJavaScriptShadowbox"; Exportklasse WebWorkerShadowbox implementiert IJavaScriptShadowbox { zerstören(): void { dieser.worker.terminate(); } Privatarbeiter!: Arbeiter; eval(Code: Zeichenfolge): void { const blob = neuer Blob([Code], { Typ: "Anwendung/Javascript" }); dieser.worker = neuer Worker(URL.createObjectURL(blob), { Anmeldeinformationen: "einschließen", }); this.worker.addEventListener("Nachricht", (ev) => { const msg = ev.data as { Kanal: Zeichenfolge; Daten: beliebig }; // konsole.log('msg.data: ', msg) wenn (!this.listenerMap.has(msg.channel)) { zurückkehren; } dies.listenerMap.get(msg.channel)!.forEach((handle) => { Griff(Nachricht.Daten); }); }); } private schreibgeschützte listenerMap = neue Map<string, ((data: any) => void)[]>(); emittieren(Kanal: Zeichenfolge, Daten: beliebig): void { diese.worker.postMessage({ Kanal: Kanal, Daten, }); } ein(Kanal: Zeichenfolge, Handle: (Daten: beliebig) => void): void { wenn (!this.listenerMap.has(channel)) { dies.listenerMap.set(channel, []); } dies.listenerMap.get(Kanal)!.push(Handle); } offByChannel(Kanal: Zeichenfolge): void { dies.listenerMap.delete(Kanal); } } 2.2 Implementierung von Web-Worker-Threadsimportiere { IEventEmitter } aus "./IEventEmitter"; export Klasse WebWorkerEventEmitter implementiert IEventEmitter { private schreibgeschützte listenerMap = neue Map<string, ((data: any) => void)[]>(); emittieren(Kanal: Zeichenfolge, Daten: beliebig): void { postMessage({ Kanal: Kanal, Daten, }); } ein(Kanal: Zeichenfolge, Handle: (Daten: beliebig) => void): void { wenn (!this.listenerMap.has(channel)) { dies.listenerMap.set(channel, []); } dies.listenerMap.get(Kanal)!.push(Handle); } offByChannel(Kanal: Zeichenfolge): void { dies.listenerMap.delete(Kanal); } init() { onmessage = (ev) => { const msg = ev.data as { Kanal: Zeichenfolge; Daten: beliebig }; wenn (!this.listenerMap.has(msg.channel)) { zurückkehren; } dies.listenerMap.get(msg.channel)!.forEach((handle) => { Griff(Nachricht.Daten); }); }; } zerstören() { dies.listenerMap.clear(); bei Nachricht = null; } } 3. Verwenden Sie WebWorkerShadowbox/WebWorkerEventEmitterHauptthreadcode const shadowbox: IJavaScriptShadowbox = neue WebWorkerShadowbox(); shadowbox.on("hallo", (name: string) => { console.log(`hallo ${name}`); }); // Der Code hier bezieht sich auf den Code des Web Worker-Threads unten shadowbox.eval(code); shadowbox.emit("öffnen"); Code des Web-Worker-Threads const em = neuer WebWorkerEventEmitter(); em.on("öffnen", () => em.emit("hallo", "liuli")); Nachfolgend sehen Sie ein schematisches Diagramm des Codeausführungsflusses. 4. Begrenzen Sie die globale API des Web Workers Wie
Tatsächlich sind Es gibt einen Artikel, der erklärt, wie man Side-Channel-Angriffe im Web über // whitelistWorkerGlobalScope.ts /** * Legen Sie die Whitelist der Web Worker-Laufzeit fest, um alle unsicheren APIs zu sperren. */ Exportfunktion whitelistWorkerGlobalScope(Liste: PropertyKey[]) { const whitelist = neues Set(Liste); const all = Reflect.ownKeys(globalThis); alle.fürJeden((k) => { wenn (whitelist.has(k)) { zurückkehren; } wenn (k === "Fenster") { console.log("Fenster: ", k); } Reflect.deleteProperty(globalThis, k); }); } /** * Whitelist globaler Werte */ Konstante Whitelist: ( | Schlüssel von Typ von global | Schlüssel von WindowOrWorkerGlobalScope | "Konsole" )[] = [ "globalThis", "Konsole", "Zeitlimit festlegen", "Zeitüberschreitung löschen", "Intervall festlegen", "Löschintervall", "Nachricht senden", "auf Nachricht", "Reflektieren", "Anordnung", "Karte", "Satz", "Funktion", "Objekt", "Boolesch", "Zeichenfolge", "Nummer", "Mathe", "Datum", "JSON", ]; whitelistWorkerGlobalScope(Whitelist); Führen Sie dann den obigen Code aus, bevor Sie den Code von Drittanbietern ausführen importiere beforeCode aus "./whitelistWorkerGlobalScope.js?raw"; Exportklasse WebWorkerShadowbox implementiert IJavaScriptShadowbox { zerstören(): void { dieser.worker.terminate(); } Privatarbeiter!: Arbeiter; eval(Code: Zeichenfolge): void { // Diese Zeile ist der Schlüssel const blob = new Blob([beforeCode + "\n" + code], { Typ: "Anwendung/Javascript", }); // Anderer Code. . . } } Da wir ts zum Schreiben des Quellcodes verwenden, müssen wir ts auch in importiere { defineConfig, Plugin } von "vite"; importiere reactRefresh von "@vitejs/plugin-react-refresh"; Importprüfer von „vite-plugin-checker“; importiere { build } von "esbuild"; importiere * als Pfad von „Pfad“; Exportfunktion BuildScript (ScriptList: String []): Plugin { const _scriptList = scriptList.map((src) => Pfad.auflösen(src)); asynchrone Funktion BuildScript(src: string) { warte auf Build({ Eintragspunkte: [src], Ausgabedatei: src.slice(0, src.length - 2) + "js", Format: "iife", Bündel: wahr, Plattform: "Browser", Quellzuordnung: "inline", allowOverwrite: true, }); console.log("Build abgeschlossen: ", Pfad.relative(Pfad.resolve(), src)); } zurückkehren { Name: "vite-plugin-build-script", async konfigurierenServer(server) { server.watcher.add(_scriptList); const scriptSet = neues Set(_scriptList); server.watcher.on("change", (Dateipfad) => { // console.log('ändern: ', Dateipfad) wenn (scriptSet.has(Dateipfad)) { BuildScript(Dateipfad); } }); }, asynchroner BuildStart() { // console.log('buildStart: ', this.meta.watchMode) wenn (dieser.meta.watchMode) { _scriptList.forEach((src) => this.addWatchFile(src)); } warte auf Promise.all(_scriptList.map(buildScript)); }, }; } // https://vitejs.dev/config/ exportiere Standard-DefineConfig({ Plugins: [ reagierenRefresh(), Prüfer({ typescript: true }), BuildScript ([Pfad.auflösen("src/utils/app/whitelistWorkerGlobalScope.ts")]), ], }); Jetzt können wir sehen, dass die globalen APIs im 5. Die wichtigsten Vorteile der Web Worker Sandbox Sie können Dies ist das Ende dieses Artikels über die Details der JavaScript-Sandbox von WebWorker. Weitere verwandte Inhalte zur JavaScript-Sandbox von WebWorker finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die verwandten Artikel weiter unten. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Verstehen Sie das CSS3-Rasterlayout in 10 Minuten
>>: Warum MySQL die Verwendung von Unterabfragen und Verknüpfungen nicht empfiehlt
Wenn Ihre MySQL-Datenbank auf einem CentOS7-Syste...
Inhaltsverzeichnis rahmen Erstklassiges Fehlerrep...
Verwenden provide+inject in Vue Zuerst müssen Sie...
Ich habe das vorliegende Projekt endlich abgeschl...
Die Zukunft von CSS ist so aufregend: Einerseits b...
Hier konzentrieren wir uns nur auf die Installati...
Als ich mich bei MySQL anmeldete, wurde mir plötz...
Dieser Artikel stellt hauptsächlich die binären O...
Vorwort Ich bin ein PHP-Programmierer, der als Pr...
Inhaltsverzeichnis Geschäftslogik Datentabellenst...
Dieser Artikel beschreibt die Installation und Ko...
MySQL ist einfach zu installieren, schnell und ve...
Erstens gibt es nur ein Änderungsereignis. change...
Inhaltsverzeichnis 1. Was ist ein Prototyp? 1.1 F...
Lassen Sie uns kurz die Konfiguration von Server ...