I've already tested this code manually adding the backslash to all the </script>
tags, and
if all the tags become <\/script>
the code works.
var iframe = document.createElement('iframe');
var html = '<html><head><script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"><\/script><script type="text/javascript">$(window).load(function(){function popo1(){alert("ciaoooo!");}popo1();$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");});<\/script></head><body><div class="eccolo"></div></body></html>';
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html);
iframe.contentWindow.document.close();
DEMO
But I need to dynamically auto-replace all the </script>
tags with <\/script>
using something like
XXX.replace(/<\/script>/ig, "<\\\/script>");
according to this post
but seems that this type of replace is actually not working...
var iframe = document.createElement('iframe');
var XXX = '<html><head><script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"><\/script><script type="text/javascript">$(window).load(function(){function popo1(){alert("ciaoooo!");}popo1();$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");});<\/script></head><body><div class="eccolo"></div></body></html>';
var YYY = XXX.replace(/<\/script>/ig, "<\\\/script>");
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(YYY);
iframe.contentWindow.document.close();
DEMO
Unfortunately I can't use .js files, so I hope that there is a way to properly do the tags replace
But what if I want to dynamically replace all the </script>
tags with <\/script>
...
In a comment below, you've said:
I'm getting the var XXX
from an input that always changes.. I just added a defined value (var XXX='<html><head>...
) in my question just for example
That's a very different thing than what's in your question. If you're saying that you'll receive input in the XXX string whose content (in memory, not a string literal) looks like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script type="text/javascript">
$(window).load(function() {
function popo1() {
alert("ciaoooo!");
}
popo1();
$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");
});
</script>
</head>
<body>
<div class="eccolo"></div>
</body>
</html>
...then than input is perfectly fine and can be used as-is to set the content of the iframe
. You don't have to do the replacement on it. The post you linked to doesn't relate to what you're doing.
But if you're saying you'll get input like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script type="text/javascript">
$(window).load(function() {
var str = "The problem is here: </script>"; // <======
});
</script>
</head>
<body>
<div class="eccolo"></div>
</body>
</html>
...then you're in the same unfortunate position as the HTML parser: You don't know when the substring </script>
actually ends a script element, or is text within a JavaScript string literal (or a comment). If you had a web page with that content, the HTML parser would conclude the script element ended immediately after The problem is here:
. And indeed, if you output that content to an iframe
via document.write
, the parser will choke on it. The line:
var str = "The problem is here: </script>";
needs to be
var str = "The problem is here: <\/script>";
// or
var str = "The problem is here: </sc" + "ript>";
// or similar
...in order to avoid tripping up the HTML parser. (It would be fine in a .js
file, but that's not your use case.)
Fundamentally, if you're receiving input with something like that in it, the person giving it to you is giving you invalid input. The substring </script>
cannot appear in JavaScript code within <script>
/</script>
tags — not in a string literal, not in a comment, nowhere.
The answer defined by the spec is: Don't try to figure it out, require that it be correct. But if you know the scripts are JavaScript, and you really really want to allow invalid input and correct it, you'll need a JavaScript parser. That sounds outrageous, but Esprima is exactly that, there's jsparser in the Meteor stuff, and there may be others. You'd scan the string you're given to find <script>
, then let the JavaScript parser take over and parse the code (you'll probably need to modify it so it knows to stop in </script>
outside of a string literal / comment). Then take the text consumed by the parser, use your replace
to convert any </script>
in the code's text to <\/script>
, and continue on.
It's non-trivial, which is why the spec doesn't require HTML parsers to do it.
But again, if the input is like your example in your question (without the backslashes you used to avoid this problem with your string literal), you don't have to do a replace
at all. Just output it to the iframe, and it will work fine.
You can create script tag programatically and append in the head tag after page is loaded.
Following is the code and DEMO
var iframe = document.createElement('iframe');
var html = '<html><head></head><body><div class="eccolo"></div></body></html>';
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html);
var script1 = iframe.contentWindow.document.createElement('script');
var script2 = iframe.contentWindow.document.createElement('script');
script2.textContent = '$(window).load(function(){function popo1(){alert("ciaoooo!");}popo1();$(".eccolo").html("<br><br><br><br>xD sygsyusgsuygsus ysg usygsuys");});'
var head = iframe.contentWindow.document.querySelector('head');
head.appendChild(script1);
script1.onload = function() {
head.appendChild(script2);
}
script1.src = 'http://code.jquery.com/jquery-1.11.0.js';
iframe.contentWindow.document.close();
Hope it helps...