How to add JavaScript code into existing iFrame us

2019-02-01 23:40发布

问题:

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:

  1. 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.

  2. 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.

  3. 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.