Das Erstellen eines Skript-Tags mit innerHTML eines div funktioniert nicht

Dieser war trivial.

Wie in Spezifikation angegeben (8.4 Parsen von HTML-Fragmenten und 8.2.3.5 Andere Parsing-Status-Flags), Zitat:

bei Verwendung von innerHTML der Browser wird

  1. Erstellen Sie einen neuen Dokumentknoten und markieren Sie ihn als HTML-Dokument.

  2. Wenn es ein Kontextelement gibt und sich das Dokument des Kontextelements im Quirks-Modus befindet, dann lassen Sie das Dokument im Quirks-Modus sein. Andernfalls, wenn es ein Kontextelement gibt und das Dokument des Kontextelements sich im Modus der eingeschränkten Quirks befindet, Lassen Sie dann das Dokument im unbegrenzten Quirks-Modus sein. Belassen Sie andernfalls das Dokument im No-Quirks-Modus.

  3. Erstellen Sie einen neuen HTML-Parser und verknüpfen Sie ihn mit dem gerade erstellten Dokumentknoten....

und beim Parsen einer <script> innen

Das Scripting-Flag wird auf "enabled" gesetzt, wenn Scripting für das Dokument, mit dem der Parser verknüpft ist, aktiviert war, als der Parser erstellt wurde, andernfalls auf "disabled".

Das Scripting-Flag kann auch dann aktiviert werden, wenn der Parser ursprünglich für den HTML-Fragment-Parsing-Algorithmus erstellt wurde, obwohl in diesem Fall keine Skriptelemente ausgeführt werden.

Es wird also nicht ausgeführt, solange Sie es mit innerHTML injizieren .

Und mit innerHTML wird das verhindern <script> Element erstellt, um dauerhaft ausgeführt zu werden.

Wie in Spezifikation (4.3.1 Das Skriptelement) angegeben, Zitat:

Das dynamische Ändern der Attribute src, type, charset, async und defer hat keine direkten Auswirkungen; diese Attribute werden nur zu bestimmten, unten beschriebenen Zeiten verwendet.

Abschluss der unten beschriebenen ist das, es analysiert nur die src -Attribut beim Einfügen des <script> zum document (egal welche, einschließlich der temporären, die bei Verwendung von innerHTML erstellt wurde .)

Solange Sie also ein Skript in das Dokument einfügen und es ausführen lassen möchten, müssen Sie script = document.createElement('script') verwenden .

Setzen Sie seine Attribute wie src und type , möglicherweise der Inhalt darin (mithilfe von script.appendChild(document.createTextNode(content)) ), hängen Sie es dann an document.body an .


Sie können stattdessen Folgendes versuchen:

var wrap = document.createElement('div');
var scr = document.createElement('script');
scr.src = scriptUrl;
scr.type = 'text/javascript';
wrap.appendChild(scr);
document.body.appendChild(wrap);

Indem Sie das script-Tag explizit erstellen, teilen Sie JS mit, dass innerHTML kein Text, sondern ein ausführbares Skript ist.


Eine mögliche Lösung, wenn Sie keine Kontrolle über den Einfügemechanismus haben und gezwungen sind, innerHTML mit script zu verwenden Beacons, besteht darin, DOM-Knoten aus den "Geister"-Knoten wieder aufzubauen.

Dies ist ein wiederkehrendes Problem in der Ad-Tech-Branche, in der viele automatisierte Systeme willkürlichen HTML-Code duplizieren (auch bekannt als Adserver ^^).

funktioniert gut in Chrome:

var s = wrap.getElementsByTagName('script');
for (var i = 0; i < s.length ; i++) {
  var node=s[i], parent=node.parentElement, d = document.createElement('script');
  d.async=node.async;
  d.src=node.src;
  parent.insertBefore(d,node);
  parent.removeChild(node);
}

(Sie können es in JSFiddle testen)


No