Start · Sprachen · JavaScript · Referenz · ShadowRoot.setHTML()

ShadowRoot.setHTML()

Methode

Parst einen HTML-String, entfernt dabei XSS-gefährliche Inhalte und ersetzt damit den gesamten Inhalt des Shadow Roots.

seit JavaScript Experimentell: Firefox 148+, Chromium nur hinter F Kategorie: webapi

Signatur

ShadowRoot.prototype.setHTML(input, options)

Beschreibung

setHTML() ist Teil der HTML Sanitizer API. Die Methode parst einen HTML-String, bereinigt das Ergebnis mit einem Sanitizer und ersetzt anschließend alle bisherigen Kindknoten des ShadowRoot durch das Ergebnis. Damit ist sie die sichere Alternative zu shadowRoot.innerHTML = ..., wenn du Markup aus nicht vertrauenswürdigen Quellen (Benutzereingaben, CMS-Inhalte, API-Antworten) in einer Web Component darstellen willst.

Die Methode ist immer XSS-sicher: Selbst wenn eine eigene Sanitizer-Konfiguration z. B. <script> oder onclick ausdrücklich erlaubt, entfernt setHTML() solche gefährlichen Elemente und Attribute (Event-Handler, javascript:-URLs usw.) trotzdem. Ohne Optionen wird die eingebaute Standardkonfiguration genutzt, die zusätzlich z. B. Kommentare, <iframe> oder <embed> entfernt.

Über options.sanitizer kannst du die Filterung weiter einschränken bzw. anpassen: entweder mit einer Sanitizer-Instanz, einem SanitizerConfig-Objekt (z. B. { elements: [...] }, removeElements, attributes, removeAttributes, replaceWithChildrenElements, comments, dataAttributes) oder dem String "default". Brauchst du tatsächlich Skripte oder Declarative Shadow DOM, ist setHTMLUnsafe() das (bewusst unsichere) Gegenstück.

Parameter

Name Typ Default Beschreibung
$input Pflicht string Der zu parsende HTML-String. Er wird wie im Body-Kontext geparst und anschließend bereinigt.
$options object {} Optionsobjekt. Einzige Eigenschaft: sanitizer.
$options.sanitizer Sanitizer | SanitizerConfig | "default" "default" Legt fest, welche Elemente und Attribute erhalten bleiben. Unsichere Inhalte werden unabhängig von dieser Einstellung immer entfernt.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Der Inhalt des Shadow Roots wird direkt ersetzt.

Beispiele

Benutzer-HTML sicher in eine Web Component rendern

class UserComment extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  set content(html) {
    // Standardkonfiguration: Skripte, Event-Handler & Co. fliegen raus
    this.shadowRoot.setHTML(html);
  }
}
customElements.define('user-comment', UserComment);

const el = document.createElement('user-comment');
document.body.append(el);
el.content = '<p onclick="alert(1)">Hallo <b>Welt</b></p><script>alert(2)</script>';

console.log(el.shadowRoot.innerHTML);
<p>Hallo <b>Welt</b></p>

Erlaubte Elemente per SanitizerConfig einschränken

const host = document.querySelector('#preview');
const shadow = host.shadowRoot ?? host.attachShadow({ mode: 'open' });

const markdownHtml = '<h1>Titel</h1><p>Text mit <a href="https://example.com" style="color:red">Link</a></p><img src="x.png">';

shadow.setHTML(markdownHtml, {
  sanitizer: {
    elements: ['p', 'a', 'strong', 'em'],
    attributes: ['href']
  }
});

console.log(shadow.innerHTML);
Titel<p>Text mit <a href="https://example.com">Link</a></p> (Hinweis: nicht erlaubte Elemente werden entfernt; die genaue Behandlung von Textinhalten hängt von der Konfiguration ab)

Wiederverwendbare Sanitizer-Instanz

const sanitizer = new Sanitizer();
sanitizer.removeElement('img');
sanitizer.removeAttribute('class');

const shadow = document.querySelector('#card').attachShadow({ mode: 'open' });
shadow.setHTML('<div class="x"><img src="a.png">Karte</div>', { sanitizer });

console.log(shadow.innerHTML);
<div>Karte</div>

Feature-Erkennung mit Fallback

const renderSafe = (shadowRoot, html) => {
  if ('setHTML' in ShadowRoot.prototype) {
    shadowRoot.setHTML(html);
  } else {
    // Fallback: nur Text, niemals ungeprüft innerHTML verwenden
    shadowRoot.textContent = html;
    // oder eine Bibliothek wie DOMPurify einsetzen
  }
};

const root = document.body.appendChild(document.createElement('div')).attachShadow({ mode: 'open' });
renderSafe(root, '<em>sicher</em><script>boom()</script>');

// Wichtig · Fallstricke

  • Kompatibilität: Die Sanitizer API ist noch experimentell. Firefox liefert sie ab Version 148 aus, in Chromium-Browsern ist sie derzeit nur hinter einem Flag verfügbar, Safari unterstützt sie noch nicht. Mach vorher eine Feature-Erkennung ('setHTML' in ShadowRoot.prototype) und nutze als Fallback z. B. DOMPurify.
  • Ältere Spezifikation: Frühe Implementierungen (Chrome 105–118 mit Flag) hatten eine abweichende API (Element.setHTML() mit anderer Sanitizer-Konfiguration). Code aus alten Tutorials funktioniert daher oft nicht mehr.
  • Ersetzt alles: Alle vorhandenen Kindknoten des Shadow Roots, auch <style>-Elemente, werden entfernt. Styles lassen sich besser über adoptedStyleSheets einbinden, dann bleiben sie erhalten.
  • Kein Declarative Shadow DOM: <template shadowrootmode> wird nicht in verschachtelte Shadow Roots umgewandelt. Dafür gibt es nur setHTMLUnsafe().
  • Sicherheit: setHTML() verhindert Skriptausführung, aber keine anderen Angriffe wie CSS-basiertes Datenabgreifen oder Phishing über Formulare und Links. Beschränke daher die erlaubten Elemente und Attribute mit einer eigenen Konfiguration so weit wie möglich. Mit Trusted Types gilt setHTML() als sicherer Einstiegspunkt und braucht keine Policy.