How do I inject javascript to a page on IE 8?

adolfojp picture adolfojp · Apr 1, 2009 · Viewed 15.1k times · Source

Lets suppose that I have the following markup:

<div id="placeHolder"></div>

and I have a JavaScript variable jsVar that contains some markup and some JavaScript.

By using Mootools 1.1 I can inject the JavaScript content into the placeholder like this:

$('placeHolder').setHTML(jsVar);

This works in Firefox, Opera, and even Safari and the resulting markup looks like this:

<div id="placeHolder">
    <strong>I was injected</strong>
    <script type="text/javascript">
        alert("I was injected too!");
    </script>
</div>

However, on IE 8 I get the following:

<div id="placeHolder">
    <strong>I was injected</strong>
</div>

Is there any way to inject the JavaScript on IE 8 or does it security model forbid me from doing this at all?

I tried Luca Matteis' suggestion of using

document.getElementById("placeHolder").innerHTML = jsVar;

instead of the MooTools code and I get the same result. This is not a MooTools issue.

Answer

Jarret Hardie picture Jarret Hardie · Apr 1, 2009

This MSDN post specifically addresses how to use innerHTML to insert javascript into a page. You are right: IE does consider this a security issue, so requires you to jump through certain hoops to get the script injected... presumably hackers can read this MSDN post as well as we can, so I'm at a loss as to why MS considers this extra layer of indirection "secure", but I digress.

From the MSDN article:

<HTML>
<SCRIPT>
function insertScript(){
    var sHTML="<input type=button onclick=" + "go2()" + " value='Click Me'><BR>";
    var sScript="<SCRIPT DEFER>";
    sScript = sScript + "function go2(){ alert('Hello from inserted script.') }";
    sScript = sScript + "</SCRIPT" + ">";
    ScriptDiv.innerHTML = sHTML + sScript;
}    
</SCRIPT>
<BODY onload="insertScript();">
    <DIV ID="ScriptDiv"></DIV>
</BODY>
</HTML>

If at all possible, you may wish to consider using a document.write injected script loading tag to increase security and reduce cross-browser incompatibility. I understand this may not be possible, but it's worth considering.