Executing <script> elements inserted with .innerHTML

Simplified ES6 version of @joshcomley's answer with an example.

No JQuery, No library, No eval, No DOM change, Just pure Javascript.

http://plnkr.co/edit/MMegiu?p=preview

var setInnerHTML = function(elm, html) {
  elm.innerHTML = html;
  Array.from(elm.querySelectorAll("script")).forEach( oldScript => {
    const newScript = document.createElement("script");
    Array.from(oldScript.attributes)
      .forEach( attr => newScript.setAttribute(attr.name, attr.value) );
    newScript.appendChild(document.createTextNode(oldScript.innerHTML));
    oldScript.parentNode.replaceChild(newScript, oldScript);
  });
}

Usage

$0.innerHTML = HTML;    // does *NOT* run <script> tags in HTML
setInnerHTML($0, HTML); // does run <script> tags in HTML

Here is a very interesting solution to your problem: http://24ways.org/2005/have-your-dom-and-script-it-too

So it would look like this instead:

<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />

You should not use the innerHTML property but rather the appendChild method of the Node: a node in a document tree [HTML DOM]. This way you are able to later call your injected code.

Make sure that you understand that node.innerHTML is not the same as node.appendChild. You might want to spend some time on the Javascript Client Reference for more details and the DOM. Hope the following helps...

Sample injection works:

<!DOCTYPE HTML>
<html>
<head>
    <title>test</title>
    <script language="javascript" type="text/javascript">
        function doOnLoad() {
            addScript('inject',"function foo(){ alert('injected'); }");
        }
    
        function addScript(inject,code) {
            var _in = document.getElementById('inject');
            var scriptNode = document.createElement('script');
            scriptNode.innerHTML = code;
            _in.appendChild(scriptNode);
        }
    </script>
</head>
<body onload="doOnLoad();">
    <div id="header">some content</div>
    <div id="inject"></div>
    <input type="button" onclick="foo(); return false;" value="Test Injected" />
</body>
</html>