可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to add a JavaScript snippet into an existing iFrame in the page using jQuery. I have the following code...
Code:
content = "<script>" + js_code + "</script>";
$('#iframe_id').contents().find('body').append(content);
But somehow this is not working. I checked some of the existing/related answers, and it seems jQuery does not quite recognize the script tags as...script tags. The iFrame is in the same domain/same port/same host, so there is no issue about cross-site scripting etc. How can I fix this?
回答1:
The problem is that the HTML parser gets confused if your script contains the closing script tag in it (</script>
) and it closes the script tag prematurely.
The solution is to escape the /
in "<\/script>"
. This works because strings in JavaScript, (and some other languages), any invalid escape sequences are just ignored, so "\l"
is treated as "l"
, and "\/"
is treated as "/"
. The HTML parser, however, doesn't use a backslash to escape them so it doesn't get confused (credits to https://stackoverflow.com/users/405681/keaukraine).
var scriptTag = "<script>alert(1)<\/script>";
$("#iframe").contents().find("body").append(scriptTag);
Original solution way
Break up that closing tag so you don't mess up the HTML parser. The other solutions on this page work because they never have the string </script>
in their code
var scriptTag = "<script>alert(1)<";
scriptTag += "/script>";
console.log(scriptTag);
$("#iframe").contents().find("body").append(scriptTag);
http://jsfiddle.net/ALpjZ/2/
回答2:
var script = "alert('hello world');";
$('#iframe').contents().find('body').append($('<script>').html(script))
works in Fiddle
回答3:
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);
}
});
}
This was the simplest way I could make it work.
回答4:
You need to escape the /script
.
It apears.
Do like google analitcs for instance
$("#iframe").contents().find("body").append(decodeURI("**%3Cscript%3E** alert(2) **%3C/script%3E**"));
replace the script
and /script
with this escaped ones
Hope it helps.
回答5:
As the iframe runs as it's own window
, you will have to also inject the import of the jquery.js file.
<script type="text/javascript" src="/jquery/jquery-ui-1.9.1.custom.js"></script>
EDIT: So I played with this a bit more and here is what I came up with.
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>"
);
This works, see here http://jsfiddle.net/WsCxj/.
So there are several points:
I am passing the entire content as one string. You have to prepend data:text/html;charset=utf-8,
and then you can set your string as src of the iframe.
I am adding the jquery.js file with an absolute path - This seems to be important, presumably because the frame has no path by itself as it's content is dynamically generated.
I split the script end tag like this <" + "/script>
because at least firefox tries to end the actual script at this point. The cleaner approach would probably be to have the js as totally separate file.
回答6:
You don't need add a tag script to execute javascript, you can do a function and apply iframe context...
using eval
function initFrame (code){
eval (code);
}
initFrame.apply ($('#iframe').contents(),[js_code]);
Without eval
var initFrame = new Function(js_code);
initFrame.apply ($('#iframe').contents(),[]);
回答7:
I cannot comment to your last post, because i'm new here and i dont have enough reputation but like i said in my post the problem was in the /script.
So escaping it ( like google does for instance ) maybe is the best option...
Well, the good news is that the problem is solved ;)
Regards
回答8:
How about setting ajax refresh with js interval function to take any data stored in file/session etc. ?
It's surely not the most lightweight mode and it involves a tiny bit php, but can do the work.