0

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

3
  • Why are you using document.open/write/close... Commented Jul 28, 2014 at 5:01
  • @ edward: I've updated my answer. The thing in that post doesn't relate to what you're doing. Commented Jul 28, 2014 at 8:03
  • Why do you think it's not working? try alert(YYY) in your demo. it have <\/script> as you want Commented Jul 28, 2014 at 15:36

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

If you absolutely must have the script in your var XXX, and can't use .js files, then you'll need to add the backslashes before the XXX variable makes its way into your script/HTML.
-1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.