Ich möchte ein JavaScript-Snippet mit jQuery zu einem vorhandenen iFrame auf der Seite hinzufügen. Ich habe folgenden Code ...
Code:
content = "<script>" + js_code + "</script>";
$('#iframe_id').contents().find('body').append(content);
Aber irgendwie funktioniert das nicht. Ich habe einige der vorhandenen/verwandten Antworten überprüft, und es scheint, dass jQuery die Skript-Tags nicht als Skript-Tags erkennt. Der iFrame befindet sich in derselben Domäne/an demselben Port/an demselben Host. Es gibt also keine Probleme mit Cross-Site-Scripting usw. Wie kann ich das beheben?
Das Problem ist, dass der HTML-Parser verwirrt wird, wenn in Ihrem Skript der schließende Skripttag (</script>
) enthalten ist und der Skripttag vorzeitig geschlossen wird.
Die Lösung besteht darin, den /
in "<\/script>"
zu umgehen. Dies funktioniert, weil Zeichenfolgen in JavaScript (und einigen anderen Sprachen), alle ungültigen Escape-Sequenzen einfach ignoriert werden, sodass "\l"
als "l"
und "\/"
als "/"
behandelt wird. Der HTML-Parser verwendet jedoch keinen Backslash, um sie zu umgehen, sodass er nicht verwirrt wird (Credits an https://stackoverflow.com/users/405681/keaukraine ).
var scriptTag = "<script>alert(1)<\/script>";
$("#iframe").contents().find("body").append(scriptTag);
Originallösung Weg
Unterbrechen Sie das schließende Tag, damit Sie den HTML-Parser nicht durcheinander bringen. Die anderen Lösungen auf dieser Seite funktionieren, weil sie niemals die Zeichenfolge </script>
in ihrem Code enthalten
var scriptTag = "<script>alert(1)<";
scriptTag += "/script>";
console.log(scriptTag);
$("#iframe").contents().find("body").append(scriptTag);
function putScriptInIframes(script, scriptId) {
var $iframes = $('iframe');
$iframes.each(function () {
var thisDoc = this.contentWindow.document;
if ( ! thisDoc.getElementById(scriptID)) {
var scriptObj = thisDoc.createElement("script");
scriptObj.type = "text/javascript";
scriptObj.id = scriptId;
scriptObj.innerHTML = script;
thisDoc.body.appendChild(scriptObj);
}
});
}
Dies war der einfachste Weg, wie ich es schaffen konnte.
var script = "alert('hello world');";
$('#iframe').contents().find('body').append($('<script>').html(script))
arbeitet in Fiddle
Sie müssen den /script
..__ entkommen. Es erscheint.
Machen Sie es zum Beispiel wie Google Analytics
$("#iframe").contents().find("body").append(decodeURI("**%3Cscript%3E** alert(2) **%3C/script%3E**"));
ersetzen Sie script
und /script
durch diese mit Escapezeichen
Ich hoffe es hilft.
Da der iframe als window
ausgeführt wird, müssen Sie auch den Import der Datei jquery.js einfügen.
<script type="text/javascript" src="/jquery/jquery-ui-1.9.1.custom.js"></script>
EDIT: Also habe ich ein bisschen mehr damit gespielt und hier ist was ich mir ausgedacht habe.
HTML
<iframe id="frame"></iframe>
JS
$("#frame").attr(
"src", "data:text/html;charset=utf-8," +
"<html>" +
"<style>.red {color: red}</style>" +
"<div class=\"test\">Test</test>" +
"<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js\"><" + "/script>" +
"<script>$(function(){ $(\".test\").addClass(\"red\")});<" + "/script>" +
"</html>"
);
Dies funktioniert, siehe hier http://jsfiddle.net/WsCxj/ .
Es gibt also mehrere Punkte:
Ich übergebe den gesamten Inhalt als eine Zeichenkette. Sie müssen data:text/html;charset=utf-8,
voranstellen und dann können Sie Ihren String als src des iframe setzen.
Ich füge die jquery.js-Datei mit einem absoluten Pfad hinzu - Dies scheint wichtig zu sein, vermutlich weil der Frame selbst keinen Pfad hat, da der Inhalt dynamisch generiert wird.
Ich teile das Skriptende-Tag wie folgt auf <" + "/script>
, da zumindest Firefox versucht, das eigentliche Skript an diesem Punkt zu beenden. Der sauberere Ansatz wäre wahrscheinlich, die js als völlig separate Datei zu haben.
Sie müssen kein Tag-Skript hinzufügen, um Javascript auszuführen, Sie können eine Funktion ausführen und Iframe-Kontext anwenden ...
mit eval
function initFrame (code){
eval (code);
}
initFrame.apply ($('#iframe').contents(),[js_code]);
Ohne eval
var initFrame = new Function(js_code);
initFrame.apply ($('#iframe').contents(),[]);
Ich kann nicht zu Ihrem letzten Beitrag kommentieren, da ich neu hier bin und nicht genug Ruf habe, aber wie ich in meinem Beitrag gesagt habe, war das Problem im/Skript.
Daher ist es vielleicht die beste Option, es zu umgehen (wie es Google zum Beispiel tut) ...
Nun, die gute Nachricht ist, dass das Problem gelöst ist;)
Grüße