Start · Sprachen · JavaScript · Referenz · Element.innerHTML

Element.innerHTML

Eigenschaft

Die Eigenschaft <code>innerHTML</code> liest oder setzt das HTML- oder XML-Markup innerhalb eines Elements (ohne shadow roots).

Kategorie: webapi

Signatur

Element.innerHTML

Beschreibung

Die Eigenschaft innerHTML des Element-Interfaces liest oder setzt das im Element enthaltene HTML- oder XML-Markup und lässt dabei in beiden Fällen shadow roots weg.

Um HTML in das Dokument einzufügen, statt den Inhalt eines Elements zu ersetzen, verwende die Methode Element.insertAdjacentHTML().

Wert: Beim Lesen der Eigenschaft wird ein String zurückgegeben, der die HTML-Serialisierung der Nachfahren des Elements enthält.

Beim Setzen der Eigenschaft wird entweder ein TrustedHTML-Objekt oder ein String akzeptiert. Der Wert wird als HTML geparst und alle Nachfahren des Elements werden durch das Ergebnis ersetzt. Wird sie auf den Wert null gesetzt, wird dieser null-Wert in den leeren String ("") umgewandelt, sodass elt.innerHTML = null äquivalent zu elt.innerHTML = "" ist.

Ausnahmen:

  • SyntaxError DOMException: Wird ausgelöst, wenn versucht wurde, den Wert von innerHTML mit einem String zu setzen, der kein wohlgeformtes HTML ist.
  • TypeError: Wird ausgelöst, wenn die Eigenschaft auf einen String gesetzt wird, während Trusted Types per CSP erzwungen werden und keine Default-Policy definiert ist.
  • NoModificationAllowedError DOMException: Wird ausgelöst, wenn versucht wurde, das HTML in einen Node einzufügen, dessen Elternknoten ein Document ist.

innerHTML liefert eine Serialisierung der verschachtelten Kind-DOM-Elemente innerhalb des Elements oder setzt HTML bzw. XML, das geparst werden soll, um den DOM-Baum innerhalb des Elements zu ersetzen.

Beachte, dass einige Browser die Zeichen < und > als &lt; und &gt; serialisieren, wenn sie in Attributwerten vorkommen. Dies dient dazu, eine potenzielle Sicherheitslücke (mutation XSS) zu verhindern, bei der ein Angreifer eine Eingabe konstruieren kann, die eine Sanitization-Funktion umgeht und einen cross-site scripting (XSS)-Angriff ermöglicht.

Shadow-DOM-Überlegungen: Die aus der Eigenschaft gelesene Serialisierung des DOM-Baums enthält keine shadow roots — wenn du einen HTML-String benötigst, der shadow roots enthält, musst du stattdessen die Methoden Element.getHTML() oder ShadowRoot.getHTML() verwenden.

Ebenso wird beim Setzen von Elementinhalten mittels innerHTML der HTML-String in DOM-Elemente ohne shadow roots geparst. So wird zum Beispiel <template> in ein HTMLTemplateElement geparst, unabhängig davon, ob das shadowrootmode-Attribut angegeben ist. Um den Inhalt eines Elements aus einem HTML-String zu setzen, der deklarative shadow roots enthält, musst du stattdessen Element.setHTMLUnsafe() oder ShadowRoot.setHTMLUnsafe() verwenden.

Sicherheitsüberlegungen: Die innerHTML-Eigenschaft ist wahrscheinlich der häufigste Vektor für cross-site scripting (XSS)-Angriffe, bei denen potenziell unsichere, von einem Benutzer bereitgestellte Strings in das DOM injiziert werden, ohne zuvor bereinigt worden zu sein. Zwar verhindert die Eigenschaft, dass <script>-Elemente ausgeführt werden, wenn sie injiziert werden, doch ist sie für viele andere Möglichkeiten anfällig, wie Angreifer HTML gestalten können, um schädliches JavaScript auszuführen. Zum Beispiel würde das folgende Beispiel den Code im error-Event-Handler ausführen, weil der src-Wert des <img> keine gültige Bild-URL ist.

Du kannst diese Probleme entschärfen, indem du immer TrustedHTML-Objekte statt Strings zuweist und Trusted Types über die CSP-Direktive require-trusted-types-for erzwingst. Dies stellt sicher, dass die Eingabe durch eine Transformationsfunktion geleitet wird, die die Möglichkeit hat, die Eingabe zu bereinigen und potenziell gefährliches Markup zu entfernen, bevor es injiziert wird.

Rückgabewert

Typ
string | TrustedHTML
Beschreibung
Ein String mit der HTML-Serialisierung der Nachfahren des Elements. Beim Setzen wird ein String oder ein TrustedHTML-Objekt akzeptiert.

Beispiele

HTML-Inhalte eines Elements lesen (JS)

const myElement = document.querySelector("#example");
const contents = myElement.innerHTML;
console.log(contents); // "\n  <p>My name is Joe</p>\n"
<p>My name is Joe</p>

Trusted Types Tinyfill

if (typeof trustedTypes === "undefined")
  trustedTypes = { createPolicy: (n, rules) => rules };

TrustedTypePolicy erstellen

const policy = trustedTypes.createPolicy("my-policy", {
  createHTML: (input) => DOMPurify.sanitize(input),
});

Inhalte eines Elements ersetzen

// The potentially malicious string
const untrustedString = "<p>I might be XSS</p><img src='x' onerror='alert(1)'>";

// Create a TrustedHTML instance using the policy
const trustedHTML = policy.createHTML(untrustedString);

// Inject the TrustedHTML (which contains a trusted string)
const element = document.querySelector("#container");
element.innerHTML = trustedHTML;

XSS-Beispiel

const name = "<img src='x' onerror='alert(1)'>";
el.innerHTML = name; // shows the alert

// Wichtig · Fallstricke

Warnung: Diese Eigenschaft parst ihre Eingabe als HTML und schreibt das Ergebnis in das DOM. APIs wie diese werden als injection sinks bezeichnet und sind potenziell ein Vektor für cross-site scripting (XSS)-Angriffe, wenn die Eingabe ursprünglich von einem Angreifer stammt. Du kannst dieses Risiko entschärfen, indem du immer TrustedHTML-Objekte statt Strings zuweist und Trusted Types erzwingst. Hinweis: Node.textContent sollte verwendet werden, wenn du weißt, dass der vom Benutzer bereitgestellte Inhalt reiner Text sein soll. Dies verhindert, dass er als HTML geparst wird.