blanks Blog: http://www.planabc.net/
Die Verwendung des
innerHTML-Attributs erfreut sich großer Beliebtheit, da es eine einfache Möglichkeit bietet, den Inhalt eines HTML-Elements vollständig zu ersetzen. Eine andere Methode ist die Verwendung der DOM Level 2 API (removeChild, createElement, appendChild). Aber offensichtlich ist die Verwendung von innerHTML zum Ändern des DOM-Baums eine sehr einfache und effektive Methode. Sie müssen sich jedoch darüber im Klaren sein, dass innerHTML einige eigene Probleme hat:
Wenn eine HTML-Zeichenfolge ein Skript-Tag (
) enthält, das als „defer“ markiert ist, kann es zu einem Skript-Injection-Angriff auf Internet Explorer kommen, wenn das innerHTML-Attribut falsch behandelt wird.
Durch das Festlegen von innerHTML werden vorhandene HTML-Elemente zerstört, die über registrierte Ereignishandler verfügen, was bei einigen Browsern zu einem potenziellen Risiko von Speicherverlusten führen kann.
Es gibt noch einige weitere kleinere Nachteile, die ebenfalls erwähnenswert sind:
Sie können keine Verweise auf die Elemente erhalten, die Sie gerade erstellt haben. Sie müssen manuell Code hinzufügen, um diese Verweise abzurufen (mithilfe von DOM-APIs).
Sie können das innerHTML-Attribut nicht für alle HTML-Elemente in allen Browsern festlegen (Internet Explorer erlaubt Ihnen beispielsweise nicht, das innerHTML-Attribut für das Zeilenelement einer Tabelle festzulegen).
Ich mache mir mehr Sorgen über die Sicherheits- und Speicherprobleme, die mit der Verwendung des innerHTML-Attributs verbunden sind. Offensichtlich ist dies kein neues Problem, und es gibt bereits talentierte Leute, die Lösungen für einige dieser Probleme gefunden haben.
Douglas Crockford hat eine Bereinigungsfunktion geschrieben, die dafür verantwortlich ist, einige Zirkelverweise zu unterbrechen, die durch die Registrierung von Ereignishandlern durch HTML-Elemente verursacht werden, und die es dem Garbage Collector ermöglicht, den mit diesen HTML-Elementen verbundenen Speicher freizugeben.
Das Entfernen von Skript-Tags aus HTML-Strings ist nicht so einfach, wie es aussieht. Ein regulärer Ausdruck kann den gewünschten Effekt erzielen, allerdings ist es schwierig zu wissen, ob er alle Möglichkeiten abdeckt. Hier ist meine Lösung:
<script>/</script>[^>]*>[Ss]*?]*>/ig
Jetzt kombinieren wir diese beiden Techniken in einer einzigen setInnerHTML-Funktion und binden die setInnerHTML-Funktion an YAHOO.util.Dom von YUI:
YAHOO.util.Dom.setInnerHTML = function (el, html) {
el = YAHOO.util.Dom.get(el);
if (!el || typeof html !== 'string ') {
return null;
}
// Zirkelverweis abbrechen
(Funktion (o) {
var a = o.attributes, i, l, n, c;
if (a) {
l = a.length; for (i = 0; i n = a[i].name;
if (typeof o[n] === 'function') {
o[n] = null;
}
}
}
a = o.childNodes;
if (a) {
l = a.length; for (i = 0; i c = o.childNodes[i];
// Untergeordnete Knoten löschen
arguments.callee(c);
// Alle über YUIs addListener für das Element registrierten Listener entfernen
YAHOO.util.Event.purgeElement(c);
}
}
})(el);
// Skript aus der HTML-Zeichenfolge entfernen und das innerHTML-Attribut festlegen <script> el.innerHTML = html.replace(/</script>[^>]*>[Ss]*?
]*>/ig, " ");
// Gibt die Referenz des ersten untergeordneten Knotens zurück
return el.firstChild;
};
Wenn diese Funktion noch etwas tun soll oder etwas im regulären Ausdruck fehlt, lassen Sie es mich bitte wissen.
<script>Natürlich gibt es viele andere Möglichkeiten, schädlichen Code in Webseiten einzuschleusen. Die setInnerHTML-Funktion normalisiert nur das Ausführungsverhalten des <br />-Tags in allen Browsern der Klasse A. Wenn Sie nicht vertrauenswürdigen HTML-Code einfügen möchten, müssen Sie ihn zuerst auf der Serverseite filtern. Es gibt viele Bibliotheken, die dies tun können.
<script defer>…</script>Originaltext: „The Problem With innerHTML“ von Julien Lecomte