2

We need to add a script to our web application. It basically adds an corporate menu.

So we've received a script to include in the body of our web application:

<!-- BEGIN NAVIGATION -->
<script type="text/javascript" src="https://intranet.local/?getCorporateJsMenu"></script>
<!-- END NAVIGATION -->

And the content of https://intranet.local/?getCorporateJsMenu basically looks like this:

document.write('<script type="text/javascript" src="..."></script>');
//....
document.write('<div>');
document.write('<ul>');
//...
document.write('<li><a href="...">...</a></li>');
//...
document.write('</ul>');
document.write('</div>');

After having placed the <!--NAVIGATION--><script... directly into the HTML body, we were experiencing severe page load performance problems.

So our idea was to add the menu with JavaScript, when everything has already been loaded with something like this:

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://intranet.local/?getCorporateJsMenu';
var domparent = jQuery('#header').get();
domparent[0].appendChild(script);

With Firebug we see, that the script element has been added to the HTML content and the script has been loaded from the network, but somehow the document.write of the loaded script doesn't get executed. Why?


We cannot modify the contents of https://intranet.local/?getCorporateJsMenu since it comes from third party.

7
  • doc.write will hose performance. you can redefine the method and collect the calls in an array to achieve a poor-man's output buffering. then something like .innerHTML=arrWrites.join(" "); Commented Jul 9, 2013 at 7:53
  • @dandavis Actually document.write() is the fastest way to create content dynamically... Commented Jul 9, 2013 at 7:56
  • @Teemu: i don't know about creating content, or how you define "fastest", but doc.write has well-documented terrible effects on page load performance... Commented Jul 9, 2013 at 8:01
  • 1
    @JMW After your update, it looks like your only chance is to contact the vendor, and ask them to fix the script, or change the vendor... Commented Jul 9, 2013 at 10:08
  • 1
    I can't see any way to override a third-party code, since you can't access a cross-domain document. And in this particular case, the error is caused at the parse time, you couldn't heal it even if it was your own code, without correcting the code in the actual file. Commented Jul 9, 2013 at 10:48

3 Answers 3

14

This happens because the script execution stops at the first found literal </script> tag, no matter if it was enclosed in the parenthesis. You need to obfuscate the ending script tag, for example:

document.write('<script type="text/javascript" src="..."><\/script>');

However, it seems you use also jQuery. Why not use the jQuery methods to load a script and add the content to a page rather than document.write()?

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

2 Comments

Why is there restriction in place? What is the purpose? And whom does it help anyway, if people can ultimately work their way around like this?
@SandeepanNath Actually it's not a restriction, it's due to the behavior of an interpreter. When ever an interpreter meets an ending script tag, it's interpreted – well – as an ending script tag. That's why an at runtime written ending tag has to look different from the actual ending tag.
4

Here is an example of hijacking document.write() to bring 21st century loading performance to legacy scripts:

<script>
    var writes = [];
    document.write = [].push.bind(writes);
</script>

<div id=targ></div>

<script type="text/javascript" src="https://intranet.local/?getCorporateJsMenu"></script>
<script>
    document.getElementById("targ").innerHTML = writes.join(" ");
</script>

I've used the patterns to support ads on a SPA site, as well as to cache embeds, and in one case to modify the content's style before injecting.

6 Comments

@Teemu: good code doesn't use document.write, so i don't see how this affects anything besides document.write() and script that use it...
I mean: d.w('blaah'); var foo = 0; d.w('some ' + foo + ' is coming');. What would happen to the non-document.write-code in your snippet?
@Teemu: it would execute the same as any other normal script, and when you innerHTML'd, the concat stuff would be in there. i really don't understand what you're getting at...
Great solution :-) But sadly, Teemu is right. the proposed solution doesn't work, because there is some javascript between the doc.writes, that attaches mouseover event handlers to the elements and doesn't find the html :-(
however, i will accept your answer, because it makes the document.writes work even though it is not a practical solution to our problem :-)
|
2

Try this:

document.write('<scr' + 'ipt type="text/javascript" src="..."></scr' + 'ipt>');

1 Comment

This is what I do to check to make sure jQuery works. During the first time that I saw actual websites use this, I thought it was really funny.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.