Signatur
Beschreibung
setHTMLUnsafe() parst die übergebene HTML-Zeichenkette zu einem DocumentFragment, filtert optional anhand eines Sanitizers Elemente und Attribute heraus und ersetzt dann alle vorhandenen Kindknoten des Shadow Roots durch das Ergebnis. Funktional ähnelt die Methode dem Setzen von shadowRoot.innerHTML, bietet aber zwei wichtige Unterschiede.
Erstens wird deklaratives Shadow DOM ausgewertet: Enthält der HTML-Code ein <template shadowrootmode="open">, wird daraus ein echter Shadow Root am umgebenden Element erzeugt. Mit innerHTML bliebe dies ein gewöhnliches, inertes <template>. Das ist praktisch für Web Components, deren Markup verschachtelte Komponenten mit eigenem Shadow DOM enthält, etwa bei serverseitig gerendertem HTML.
Zweitens kann ein Sanitizer übergeben werden. Anders als bei setHTML() werden dabei aber nicht automatisch XSS-gefährliche Inhalte wie <script> oder onclick-Attribute entfernt. Entfernt wird nur, was die Sanitizer-Konfiguration ausdrücklich verbietet. Daher kommt das „Unsafe“ im Namen.
Benutzen Sie die Methode nur für vertrauenswürdiges Markup (eigene Templates, geprüfte Serverantworten) oder zusammen mit Trusted Types. Für Benutzereingaben und fremde Inhalte ist ShadowRoot.setHTML() die sichere Wahl.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $input Pflicht | string | TrustedHTML | Das HTML, das geparst und in den Shadow Root eingefügt wird. Wenn Trusted Types per CSP erzwungen werden (require-trusted-types-for 'script'), muss ein TrustedHTML-Objekt übergeben werden. |
|
| $options | object | {} | Optionales Konfigurationsobjekt. |
| $options.sanitizer | Sanitizer | SanitizerConfig | "default" | kein Filter | Eine Sanitizer-Instanz, ein Konfigurationsobjekt (z. B. { elements: [...], removeAttributes: [...] }) oder "default". Ohne Angabe wird nichts gefiltert. Unsichere Elemente werden auch mit Sanitizer nur entfernt, wenn die Konfiguration das ausdrücklich verlangt. Diese Option wird noch nicht von allen Browsern unterstützt. |
Rückgabewert
Beispiele
Shadow-DOM-Inhalt einer Web Component setzen
class InfoCard extends HTMLElement {
connectedCallback() {
const root = this.attachShadow({ mode: 'open' });
// Vertrauenswürdiges, eigenes Template
root.setHTMLUnsafe(`
<style>:host { display: block; border: 1px solid #ccc; padding: 1rem; }</style>
<h2><slot name="titel">Ohne Titel</slot></h2>
<slot></slot>
`);
}
}
customElements.define('info-card', InfoCard);
const card = document.createElement('info-card');
document.body.append(card);
console.log(card.shadowRoot.querySelector('h2') !== null);
Deklaratives Shadow DOM verschachtelter Elemente auswerten
const host = document.createElement('div');
const root = host.attachShadow({ mode: 'open' });
const markup = `
<user-badge>
<template shadowrootmode="open">
<span part="name">Ada Lovelace</span>
</template>
</user-badge>`;
root.setHTMLUnsafe(markup);
const badge = root.querySelector('user-badge');
console.log(badge.shadowRoot?.querySelector('span').textContent);
// Zum Vergleich: innerHTML erzeugt keinen Shadow Root
root.innerHTML = markup;
console.log(root.querySelector('user-badge').shadowRoot);
Mit Sanitizer-Konfiguration bestimmte Elemente entfernen
const host = document.querySelector('#vorschau');
const root = host.shadowRoot ?? host.attachShadow({ mode: 'open' });
const html = '<p>Hallo <b>Welt</b></p><iframe src="https://example.com"></iframe>';
// Entfernt nur das, was in der Konfiguration steht, also hier <iframe>
root.setHTMLUnsafe(html, {
sanitizer: { removeElements: ['iframe'] }
});
console.log(root.innerHTML);
Zusammen mit Trusted Types verwenden
// Falls Trusted Types verfügbar ist, wird eine Policy angelegt
const policy = window.trustedTypes?.createPolicy('shadow-html', {
createHTML: (s) => s.replace(/<script[\s\S]*?<\/script>/gi, '')
});
const host = document.createElement('section');
const root = host.attachShadow({ mode: 'open' });
const raw = '<p>Inhalt</p><script>alert(1)<\/script>';
root.setHTMLUnsafe(policy ? policy.createHTML(raw) : raw);
console.log(root.childElementCount);
// Wichtig · Fallstricke
- XSS-Gefahr: Die Methode bereinigt nicht automatisch. Event-Handler-Attribute wie
onerrorauf<img>werden ausgeführt, sobald das Element geladen wird. Geben Sie niemals ungeprüfte Benutzereingaben hinein. Nutzen Sie dafürsetHTML(). - Eingefügte
<script>-Elemente werden wie beiinnerHTMLnicht ausgeführt. Andere Angriffswege (Inline-Handler,javascript:-URLs) funktionieren aber weiterhin. - Trusted Types / CSP: Ist
require-trusted-types-for 'script'aktiv, löst eine normale Zeichenkette einenTypeErroraus. Übergeben Sie dann einTrustedHTML-Objekt. - Der gesamte bisherige Inhalt des Shadow Roots wird ersetzt. Event-Listener an alten Knoten gehen dabei verloren.
- Kompatibilität: Die Methode selbst ist seit 2024 in allen großen Browsern verfügbar (Chrome/Edge 124, Firefox 123, Safari 17.4). Die Option
sanitizergehört zur neueren Sanitizer API und wird bisher nur eingeschränkt unterstützt. Browser ohne Unterstützung ignorieren die Option still, es wird dann also nichts gefiltert. Prüfen Sie die Verfügbarkeit, zum Beispiel mit'Sanitizer' in window. - Die Methode gibt es auch als
Element.prototype.setHTMLUnsafe()sowie als statische MethodeDocument.parseHTMLUnsafe().