Ich habe ein Skript, das mithilfe von Inhalten Inhalte in ein Element einfügt innerHTML
.
Der Inhalt könnte zum Beispiel sein:
<script type="text/javascript">alert('test');</script>
<strong>test</strong>
Das Problem ist, dass der Code im <script>
Tag nicht ausgeführt wird. Ich habe ein bisschen gegoogelt, aber es gab keine offensichtlichen Lösungen. Wenn ich den Inhalt mit jQuery eingefügt habe, wurden $(element).append(content);
die Skriptteile eval
vor dem Einfügen in das DOM erstellt.
Hat jemand einen Codeausschnitt, der alle <script>
Elemente ausführt ? Der jQuery-Code war etwas komplex, so dass ich nicht wirklich herausfinden konnte, wie es gemacht wurde.
Bearbeiten :
Durch einen Blick in den jQuery-Code konnte ich herausfinden, wie jQuery dies tut, was zu folgendem Code führte:
Demo:
<div id="element"></div>
<script type="text/javascript">
function insertAndExecute(id, text)
{
domelement = document.getElementById(id);
domelement.innerHTML = text;
var scripts = [];
ret = domelement.childNodes;
for ( var i = 0; ret[i]; i++ ) {
if ( scripts && nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
}
}
for(script in scripts)
{
evalScript(scripts[script]);
}
}
function nodeName( elem, name ) {
return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
}
function evalScript( elem ) {
data = ( elem.text || elem.textContent || elem.innerHTML || "" );
var head = document.getElementsByTagName("head")[0] || document.documentElement,
script = document.createElement("script");
script.type = "text/javascript";
script.appendChild( document.createTextNode( data ) );
head.insertBefore( script, head.firstChild );
head.removeChild( script );
if ( elem.parentNode ) {
elem.parentNode.removeChild( elem );
}
}
insertAndExecute("element", "<scri"+"pt type='text/javascript'>document.write('This text should appear as well.')</scr"+"ipt><strong>this text should also be inserted.</strong>");
</script>
javascript
dom
eval
innerhtml
Phidah
quelle
quelle
function testFunction(){ alert('test'); }
zu dem in innerHTML eingefügten Code, und dann versuche, sie aufzurufen, heißt es, dass die Funktion nicht definiert ist.Antworten:
Das Skript des OP funktioniert in IE 7 nicht. Mit Hilfe von SO ist hier ein Skript, das Folgendes tut:
quelle
$(parent).html(code)
- siehe meine Antwort unten.if (nodeName(child, "script" ) && (!child.type || child.type.toLowerCase() === "text/javascript")) { scripts.push(child); } else { exec_body_scripts(child); }
elem.src
diesrc
Eigenschaft des erstellten Skriptelements zu überprüfen und bedingt festzulegen, anstatt dessen Textinhalt festzulegen.eval
Trick verwenden, anstatt ein<script>
Element zu erstellen und es in das einzufügen<head>
? Beide führen JS-Code aus, ohne den aktuellen Abschluss verfügbar zu machen.@phidah ... Hier ist eine sehr interessante Lösung für Ihr Problem: http://24ways.org/2005/have-your-dom-and-script-it-too
Also würde es stattdessen so aussehen:
<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />
quelle
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" onload="alert('test');">
wenn Sie eine nutzlose http-Anforderung verhindern möchten.style="display:none;
), um das Symbol für kaputte Bilder zu verbergen<style>
ist es besser als<img>
, weil es keine Netzwerkanfrage machtHier ist ein kürzeres, effizienteres Skript, das auch für Skripte mit der
src
Eigenschaft funktioniert :Hinweis:
eval
Wenn es nicht ordnungsgemäß verwendet wird, kann es zwar zu einer Sicherheitslücke kommen, es ist jedoch viel schneller als das Erstellen eines Skript-Tags im laufenden Betrieb.quelle
eval
wurde entwickelt, um Benutzer zu verletzen. Jede dynamische Skriptausführung ist ein Risiko, und deshalb ruft CSP sie auf,'unsafe-eval'
weil sie es ist. Sie beeinträchtigen auch die Sicherheit Ihrer Websites, wenn Sie sie in einer Bibliothek verwenden, da sie diese nicht deaktivieren können.src
Eigenschaft werden asynchron heruntergeladen und bei Ankunft ausgeführt. Bestellung bleibt nicht erhalten. Inline-Skripte werden auch außerhalb der Reihenfolge synchron vor den asynchronen ausgeführt.Sie sollten nicht die innerHTML-Eigenschaft verwenden, sondern die appendChild-Methode des Knotens: einen Knoten in einem Dokumentbaum [HTML DOM]. Auf diese Weise können Sie später Ihren injizierten Code aufrufen.
Stellen Sie sicher, dass Sie verstehen, dass dies
node.innerHTML
nicht dasselbe ist wienode.appendChild
. Möglicherweise möchten Sie einige Zeit in der Javascript-Client-Referenz verbringen, um weitere Informationen und das DOM zu erhalten. Hoffe das Folgende hilft ...Probeninjektion funktioniert:
Grüße,
quelle
try this, look how clever I am
Antworten. Verdient eine UV, es hat meine.var _in = document.getElementById(inject);
, Meiner Ansicht nach.Vereinfachte ES6-Version von @ joshcomleys Antwort mit einem Beispiel.
Keine JQuery, keine Bibliothek, keine Auswertung, keine DOM-Änderung, nur reines Javascript.
http://plnkr.co/edit/MMegiu?p=preview
Verwendung
quelle
setInnerHtml
nichtsetInnerHTML
setInnerHTML
abersetInnerHtml
innerhalb derrunB
Funktion aufgerufen wird . Daher funktioniert das Beispiel nichtProbieren Sie dieses Snippet aus:
quelle
Es funktioniert in Chrome in meinem Projekt
quelle
Eine Lösung ohne "eval":
Dies klont im Wesentlichen das Skript-Tag und ersetzt dann das blockierte Skript-Tag durch das neu generierte, wodurch die Ausführung ermöglicht wird.
quelle
scriptNode.innerHTML = code
funktionierte nicht für IE. Das einzige, was zu tun ist, ist durch zu ersetzenscriptNode.text = code
und es funktioniert gutquelle
Es ist einfacher, jquery zu verwenden,
$(parent).html(code)
anstattparent.innerHTML = code
:Dies funktioniert auch mit Skripten, die
document.write
Skripte verwenden und übersrc
Attribute geladen werden . Leider funktioniert auch dies nicht mit Google AdSense-Skripten.quelle
Mach einfach:
quelle
Sie können einen Blick auf diesen Beitrag werfen . Der Code könnte folgendermaßen aussehen:
quelle
Dank Larrys Skript, das in IE10 perfekt funktioniert hat, habe ich Folgendes verwendet:
quelle
Ausdehnung von Larry. Ich habe es rekursiv gemacht, den gesamten Block und die untergeordneten Knoten zu durchsuchen.
Das Skript ruft jetzt auch externe Skripte auf, die mit dem Parameter src angegeben werden. Skripte werden an den Kopf angehängt, anstatt eingefügt und in der Reihenfolge platziert, in der sie gefunden wurden. So bleiben speziell Bestellskripte erhalten. Und jedes Skript wird synchron ausgeführt, ähnlich wie der Browser das anfängliche Laden des DOMs handhabt. Wenn Sie also einen Skriptblock haben, der jQuery von einem CDN aufruft und dann der nächste Skriptknoten jQuery verwendet ... Kein Problem! Oh, und ich habe die angehängten Skripte mit einer serialisierten ID versehen, die auf dem basiert, was Sie im Tag-Parameter festgelegt haben, damit Sie herausfinden können, was von diesem Skript hinzugefügt wurde.
quelle
Versuchen Sie dies, es funktioniert für mich auf Chrome, Safari & Firefox:
Beachten Sie jedoch, dass das folgende div-verschachtelte Skript NICHT ausgeführt wird:
Damit ein Skript ausgeführt werden kann, muss es als Knoten erstellt und dann als untergeordnetes Element angehängt werden. Sie können sogar ein Skript in ein zuvor injiziertes div anhängen und es wird ausgeführt (ich bin bereits darauf gestoßen, als ich versucht habe, den Ad-Server-Code zum Laufen zu bringen):
quelle
Die Antwort von Lambder ausgeben
Sie können das base64-Image verwenden, um Ihr Skript zu erstellen und zu laden
Oder wenn Sie eine haben
Iframe
, können Sie sie stattdessen verwendenquelle
Ich brauchte etwas Ähnliches, aber das Skript musste an derselben Stelle wie das ursprüngliche Skript verbleiben oder neu erstellt werden, da mein Skript auf die Position des Skript-Tags im DOM abzielt, um / Zielelemente zu erstellen. Ich habe das Skript auch rekursiv gemacht, um sicherzustellen, dass es auch funktioniert, wenn es mehr als eine Ebene tiefer liegt.
HINWEIS: Ich verwende
const
hier, wenn Sie einen älteren Browser haben, verwenden Sie einfachvar
.quelle
Diese neue Hilfsfunktion wurde in TypeScript erstellt. Vielleicht wird es jemand zu schätzen wissen. Wenn Sie die Typdeklaration aus dem Skriptparameter entfernen, handelt es sich nur um einfaches JS.
quelle
Versuchen Sie die Funktion eval ().
Dies ist ein echtes Beispiel aus einem Projekt, das ich entwickle. Danke an diesen Beitrag
quelle
Hier ist meine Lösung in einem aktuellen Projekt.
quelle