Worker: Worker() Konstruktor
Baseline
Weitgehend verfügbar
*
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Juli 2015 browserübergreifend verfügbar.
* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.
Hinweis: Diese Funktion ist in Web Workers verfügbar, mit Ausnahme von Service Workers.
Warnung:
Dieses Skript, das dem url Element übergeben wird, wird ausgeführt.
APIs wie diese sind als Injection Sinks bekannt und können potenziell ein Vektor für Cross-Site Scripting (XSS) Angriffe sein.
Sie können dieses Risiko mindern, indem Sie eine Content Security Policy (CSP) haben, die die Orte einschränkt, von denen Skripte geladen werden können, und indem Sie immer TrustedScriptURL Objekte anstelle von Strings zuweisen und Trusted Types durchsetzen.
Weitere Informationen finden Sie unter Sicherheitsüberlegungen.
Der Worker() Konstruktor erstellt ein Worker Objekt, das das klassische Skript oder Modul an der angegebenen URL ausführt.
Syntax
new Worker(url)
new Worker(url, options)
Parameter
url-
Ein
TrustedScriptURLObjekt oder ein String, der die URL des Skripts oder Moduls darstellt, das der Worker ausführen wird.Diese muss mit dem Dokument des Anrufers gleichherkunft sein oder eine
blob:oderdata:URL sein. Die URL wird relativ zum aktuellen Standort der HTML-Seite aufgelöst. optionsOptional-
Ein Objekt, das Options-Eigenschaften enthält, die beim Erstellen der Objektinstanz festgelegt werden können. Verfügbare Eigenschaften sind wie folgt:
credentials-
Ein String, der angibt, ob der Browser Anmeldeinformationen sendet, wenn Module in einen Modul-Worker importiert werden. Die erlaubten Werte sind dieselben, die an die
fetch()Anfrage übergeben werden können:omit,same-originoderinclude. Der Standardwert istsame-origin(Anmeldeinformationen nur für gleichherkunft Anfragen einschließen).Dies wird bei klassischen Workern ignoriert.
name-
Ein String, der einen identifizierenden Namen für den
DedicatedWorkerGlobalScopeangibt, der den Geltungsbereich des Workers darstellt, was hauptsächlich für Debugging-Zwecke nützlich ist. type-
Ein String, der den Typ des zu erstellenden Workers angibt. Der Wert kann
classicodermodulesein. Der Standardwert istclassic.
Ausnahmen
NetworkErrorDOMException-
Wird ausgelöst, wenn der MIME-Typ des Worker-Skripts falsch ist. Es sollte immer
text/javascriptsein (aus historischen Gründen könnten andere JavaScript MIME-Typen akzeptiert werden). SecurityErrorDOMException-
Wird ausgelöst, wenn dem Dokument nicht erlaubt ist, Worker zu starten, z.B. wenn die URL eine ungültige Syntax hat oder die Same-Origin-Policy verletzt wird.
SyntaxErrorDOMException-
Wird ausgelöst, wenn
urlnicht analysiert werden kann. TypeError-
Wird ausgelöst, wenn der
urlParameter ein String ist, während Trusted Types durch eine CSP durchgesetzt werden und keine Standardrichtlinie definiert ist.
Beschreibung
Der Worker() Konstruktor erstellt ein Worker Objekt, das das klassische Skript oder Modul an der angegebenen URL ausführt.
Das Skript muss gleichherkunft mit dem zugehörigen Dokument sein, darf jedoch selbst Skripte oder Module importieren, die aus verschiedenen Ursprüngen stammen (falls von CORS und anderen Einschränkungen erlaubt). Wenn ein Worker mit verschiedenen Ursprüngen erforderlich ist, müssen Benutzer ihn von einem zwischengeschalteten gleichherkunft Worker oder einem Blob laden.
Modul- und klassische Worker
Ein klassischer Worker ist einer, der aus einem klassischen Skript erstellt wird, während ein Modul-Worker aus einem ECMAScript-Modul erstellt wird. Der Typ des Workers wirkt sich auf die Worker-Konstruktoroptionen aus, auf die Art, wie das Worker-Skript abgerufen und ausgeführt wird.
Der folgende Code zeigt zwei Möglichkeiten, wie Sie einen klassischen Worker konstruieren können, und auch, wie Sie den type als "module" angeben, um einen Modul-Worker zu erstellen.
In beiden Fällen muss das Skript gleichherkunft mit dem ladenden Dokument sein und wird relativ zum Standort des startenden Dokuments aufgelöst.
// Construct a classic worker
const worker1 = new Worker("worker_classic.js");
const worker2 = new Worker("worker_classic.js", {
type: "classic",
});
// Construct a module worker
const worker3 = new Worker("worker_module.js", {
type: "module",
});
Modul-Worker und ihre Abhängigkeiten werden unter Verwendung der ECMAScript-Modul-Semantik geladen und ausgeführt:
- Abhängigkeiten werden über statische
importAnweisungen importiert - Asynchron mit CORS abgerufen.
- Alle Module werden aufgelöst, bevor irgendein Code ausgeführt wird
- Müssen mit dem Medientyp
Content-Type: text/javascriptbedient werden - Ausgeführt im Strict mode
Klassische Worker werden als Skripte abgerufen und ausgeführt:
- Abhängigkeiten werden mit der Methode
WorkerGlobalScope.importScripts()importiert - Synchron im
no-corsModus abgerufen
Import von Skripten oder Modulen
Modul-Worker können ECMAScript-Module mithilfe von import Anweisungen importieren.
Module werden mit CORS abgerufen, sodass Cross-Origin-Module mit dem Access-Control-Allow-Origin Header bereitgestellt werden müssen, um geladen zu werden.
Entwickler können angeben, ob Anmeldeinformationen in Cross-Origin-Imports gesendet werden sollen oder nicht.
Klassische Worker können Skripte (aber keine Module) mit der Methode WorkerGlobalScope.importScripts() importieren.
Im Gegensatz zu Modulen werden Skripte im no-cors Modus abgerufen und können Cross-Origin angefordert werden, auch wenn der Server die entsprechenden CORS-Header nicht setzt.
Anmeldeinformationen werden bei Imports gleichherkunft gesendet, aber in der Regel nicht bei Cross-Origin-Anfragen.
Darüber hinaus muss, wenn das Dokument eine Content Security Policy (CSP) hat, die Ursprünge importierter Skripte oder Module erlaubt sein.
Für Module werden die erlaubten Quellen in worker-src (mit Rückgriff auf script-src und default-src Direktiven) angegeben, während für klassische Skripte die Quellen in script-src (mit Rückgriff auf default-src Direktiven) spezifiziert werden.
data: und blob: URLs
data: URLs können an den url Parameter übergeben werden, haben jedoch einen opaque_origin, was sie zu Cross-Origin für alle anderen Ursprünge, einschließlich ihres Eigentümers, macht.
Folglich kann der Worker zwar noch mit seinem Eigentümer über postMessage() kommunizieren, aber sein Zugriff auf andere externe Ressourcen ist stark eingeschränkt.
Beispielsweise würde eine Worker-fetch() Anfrage Cross-Origin zu seiner eigenen Seite sein, und jede Anfrage an einen beliebigen Ursprung muss von CORS gewährt werden.
blob: URLs sollten stattdessen, wo möglich, verwendet werden, da die URL den Ursprung des Dokuments erbt, das sie erstellt hat.
Dies stellt sicher, dass ein Worker, der mit einer blob: URL erstellt wird, gleichherkunft mit der Seite ist, die ihn erstellt hat.
Beachten Sie, dass, wenn Sie eine Content Security Policy (CSP) verwenden, um zu beschränken, welche Ressourcen in Ihren Worker geladen werden können, Sie den blob: Ursprung erlauben müssen.
Überlegungen für Bundler
Bundler wie webpack, Vite und Parcel empfehlen, URLs, die relativ zu import.meta.url sind, an den Worker() Konstruktor zu übergeben.
Zum Beispiel:
const myWorker = new Worker(new URL("worker.js", import.meta.url));
Dies macht den Pfad relativ zum aktuellen Skript anstatt zur aktuellen HTML-Seite, was dem Bundler erlaubt, sicher Optimierungen wie Umbenennung durchzuführen (weil andernfalls die worker.js URL auf eine Datei zeigen könnte, die nicht vom Bundler kontrolliert wird, sodass keine Annahmen getroffen werden können).
Sicherheitsüberlegungen
Das Skript oder Modul, das durch das url Argument angegeben wird, wird im Web Worker-Kontext ausgeführt und kann selbst andere Skripte aus derselben Herkunft und aus verschiedenen Ursprüngen importieren.
Wenn die url von einem Benutzer bereitgestellt wird, ist dies ein möglicher Vektor für Cross-Site Scripting (XSS) Angriffe.
Während Web Worker keinen direkten Zugriff auf das besitzende Dokument oder Fenster haben, ist es dennoch äußerst riskant, willkürlich URLs von nicht vertrauenswürdigen Ursprüngen zu akzeptieren und auszuführen. Für Modul-Worker, aber nicht für klassische Worker, wird CORS kontrollieren, welche Ressourcen von verschiedenen Ursprüngen angefordert werden können.
Eine Website sollte auch kontrollieren, welche Skripte mit einer Content Security Policy (CSP) mit der worker-src Direktive (oder einem Rückgriff auf child-src, script-src oder default-src) ausgeführt werden dürfen.
Dies kann Skripten auf diejenigen vom aktuellen Ursprung oder eine spezifische Menge von Ursprüngen oder sogar bestimmte Dateien beschränken.
Wenn Sie diese Eigenschaft verwenden und Trusted Types durchsetzen (mithilfe der require-trusted-types-for CSP Direktive), müssen Sie immer TrustedScriptURL Objekte anstelle von Strings zuweisen.
Dies stellt sicher, dass die Eingabe durch eine Transformationsfunktion geleitet wird, die die Möglichkeit hat, URLs, die vom Worker benötigt werden, abzulehnen oder zu modifizieren, bevor sie abgerufen werden.
Beispiele
Aus Gründen der Kürze verwendet nur das erste Beispiel unten trusted types. In der Produktion sollte Ihr Code immer trusted types verwenden, wenn Daten, die von Benutzern stammen, in Injection Sinks übergeben werden.
Verwendung von Trusted Types
Um das Risiko von XSS zu mindern, sollten wir immer TrustedScriptURL Instanzen an die Worker-URL anstelle von Strings übergeben.
Wir müssen dies auch tun, wenn wir trusted types aus anderen Gründen durchsetzen und einige Quellen erlauben möchten, die zugelassen wurden (durch CSP: worker-src).
Trusted Types werden noch nicht von allen Browsern unterstützt, daher definieren wir zuerst das trusted types tinyfill. Dies fungiert als transparenter Ersatz für die JavaScript-API der Trusted Types:
if (typeof trustedTypes === "undefined")
trustedTypes = { createPolicy: (n, rules) => rules };
Als nächstes erstellen wir eine TrustedTypePolicy, die eine createScriptURL() Methode definiert, um Eingabestrings in TrustedScriptURL Instanzen zu transformieren.
Für den Zweck dieses Beispiels gehen wir davon aus, dass wir eine vordefinierte Menge von URLs im workerScriptAllowList Array erlauben und alle anderen Skripte protokollieren möchten.
const workerScriptAllowList = [
// Some list of allowed URLs
];
const policy = trustedTypes.createPolicy("worker-url-policy", {
createScriptURL(input) {
if (workerScriptAllowList.includes(input)) {
return input; // allow the script
}
console.log(`Script not in workerScriptAllowList: ${input}`);
return ""; // Block the script
},
});
Als nächstes verwenden wir unser policy Objekt, um ein trustedScriptURL Objekt aus einem potenziell unsicheren Eingabestring zu erstellen und dieses an den Worker zu übergeben.
// The potentially malicious worker URL
// We won't be including untrustedScript in our workerScriptAllowList array
const untrustedScriptURL = "https://evil.example.com/naughty.js";
// Create a TrustedScriptURL instance using the policy
const trustedScriptURL = policy.createScriptURL(untrustedScriptURL);
// Construct the worker with the trusted URL
const myWorker = new Worker(trustedScriptURL);
Erstellung eines klassischen Workers
Der folgende Codeausschnitt zeigt die Erstellung eines klassischen Worker Objekts mit dem Worker() Konstruktor und die anschließende Nutzung des Objekts:
const myWorker = new Worker("worker.js");
const first = document.querySelector("input#number1");
first.onchange = () => {
myWorker.postMessage(first.value);
console.log("Message posted to worker");
};
Für ein vollständiges Beispiel siehe unser Einfaches Beispiel für dedizierte Worker (dedizierten Worker ausführen).
Laden eines Cross-Origin Modul-Workers aus einem Blob
Dieses Beispiel zeigt eine Methode, die ein Cross-Origin Modul-Worker-Skript abrufen und laden kann und es dann als Blob in Ihren Worker lädt (ein klassisches Skript könnte auf die gleiche Weise geladen werden):
async function loadWorker() {
const response = await fetch("https://other_origin.com/worker.js");
const script = await response.text();
// Create a blob that contains the fetched script, and then create a URL from that blob
const blob = new Blob([script], { type: "application/javascript" });
const workerUrl = URL.createObjectURL(blob);
try {
const worker = new Worker(workerUrl, { type: "module" });
} catch (e) {
console.error(`Cross-origin worker module failed to load: ${e}`);
}
}
loadWorker();
Der erste Abruf wird mit CORS durchgeführt, daher muss die other_origin.com Antwort den Access-Control-Allow-Origin Header enthalten, wie gezeigt:
Access-Control-Allow-Origin "https://my_origin.com"
Wenn Sie außerdem eine CSP verwenden, müssen Sie den blob: Ursprung für worker-src erlauben, damit dieser in das Dokument geladen werden kann:
Content-Security-Policy worker-src 'self' https://other_origin.com blob:
Spezifikationen
| Spezifikation |
|---|
| HTML> # dom-worker-dev> |