Signatur
Beschreibung
setHTML() gehört zur HTML Sanitizer API und ist die sichere Alternative zu innerHTML. Der übergebene String wird im Kontext des Elements geparst, anschließend bereinigt und dann als neuer Unterbaum eingefügt. Vorhandene Kindknoten werden vollständig ersetzt.
Das Besondere daran: setHTML() ist immer XSS-sicher. Auch mit einer freizügigen Konfiguration werden gefährliche Inhalte entfernt, z. B. <script>, Event-Handler-Attribute wie onclick und javascript:-URLs. Mit der Konfiguration kannst du also nur weiter einschränken, aber nie Unsicheres erlauben. Wenn du solche Inhalte bewusst brauchst, gibt es setHTMLUnsafe().
Typische Einsatzfälle sind Inhalte aus Benutzereingaben, Kommentaren, Markdown-Renderern, CMS-Feldern oder Antworten fremder APIs, die als HTML dargestellt werden sollen. Ohne Optionen gilt die eingebaute Standard-Konfiguration, die gängige Formatierungselemente erlaubt. Mit einem Sanitizer-Objekt oder einem SanitizerConfig-Wörterbuch legst du genau fest, welche Elemente und Attribute erlaubt sind.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $input Pflicht | string | Der HTML-String, der geparst, bereinigt und eingefügt werden soll. | |
| $options | object | {} | Optionales Objekt mit der Eigenschaft sanitizer. |
| $options.sanitizer | Sanitizer | SanitizerConfig | "default" | "default" | Legt die Bereinigungsregeln fest: eine Sanitizer-Instanz, ein Konfigurationsobjekt (z. B. { elements: [...], attributes: [...] }) oder "default" für die eingebaute Standard-Konfiguration. Unsichere Inhalte werden in jedem Fall entfernt. |
Rückgabewert
Beispiele
Benutzerkommentar sicher anzeigen
const kommentar = 'Hallo <b>Welt</b><img src=x onerror="alert(1)"><script>alert(2)</script>';
const box = document.querySelector('#kommentar');
// Standard-Konfiguration: Skripte und Event-Handler werden entfernt
box.setHTML(kommentar);
console.log(box.innerHTML);
Nur bestimmte Elemente erlauben (SanitizerConfig)
const eingabe = '<h1>Titel</h1><p>Text mit <a href="https://example.com" title="Link">Link</a> und <em>Betonung</em></p>';
const ziel = document.querySelector('#vorschau');
ziel.setHTML(eingabe, {
sanitizer: {
elements: ['p', 'em', 'strong', { name: 'a', attributes: ['href'] }]
}
});
// <h1> ist nicht erlaubt, das title-Attribut ebenfalls nicht
console.log(ziel.innerHTML);
Wiederverwendbarer Sanitizer mit Feature-Erkennung
const renderMarkdownHtml = (el, html) => {
if (typeof el.setHTML === 'function' && 'Sanitizer' in window) {
const sanitizer = new Sanitizer({
removeElements: ['img', 'iframe'],
comments: false
});
el.setHTML(html, { sanitizer });
} else {
// Fallback: nur Text anzeigen (oder eine Bibliothek wie DOMPurify nutzen)
el.textContent = html;
}
};
renderMarkdownHtml(document.querySelector('#artikel'), '<p>Hallo<!-- intern --><img src="a.png"></p>');
console.log(document.querySelector('#artikel').innerHTML);
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Sanitizer API ist neu und noch nicht in allen Browsern verfügbar (Firefox ab Version 148, Chromium-Unterstützung wird gerade eingeführt). Prüfe das vorher mit
typeof Element.prototype.setHTML === 'function'und halte einen Ausweichweg bereit (z. B. DOMPurify odertextContent). - Alte API-Form: Frühere experimentelle Versionen (z. B. Chrome 105 hinter einem Flag) hatten eine andere Konfigurationsform. Diese Versionen wurden wieder entfernt. Ältere Beispiele im Netz, etwa mit
allowElements, funktionieren deshalb nicht mehr. - Sicherheit:
setHTML()entfernt unsichere Inhalte immer, auch wenn die Konfiguration sie ausdrücklich erlaubt. Wer<script>oder Event-Handler braucht, muss bewusstsetHTMLUnsafe()verwenden und selbst für die Sicherheit sorgen. Trotzdem gilt: Bereinigung ersetzt keine Content Security Policy. CSP und Trusted Types bleiben als zusätzliche Schutzschicht sinnvoll. - Eine ungültige Konfiguration (z. B. dasselbe Element gleichzeitig in
elementsundremoveElements) löst einenTypeErroraus. - Auf einem
<script>-Element als Ziel fügtsetHTML()nichts ein. - Nicht erlaubte Elemente werden standardmäßig samt Inhalt entfernt. Wenn nur das Element wegfallen und sein Text erhalten bleiben soll, trage es in
replaceWithChildrenElementsein. - Für Shadow DOM gibt es
ShadowRoot.setHTML(), für ganze DokumenteDocument.parseHTML().