Dynamically added javascript with external script doesn't get executed By Admin

So this is our scenario... First thing we do is, we append a piece of javascript code which adds external script to document like this:

(function() {
     var e = document.createElement('script'); e.type = 'text/javascript'; e.async = true; e.src = 'http://blabla.com/script.js';
     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(e, s);
})();
Then in script.js following happens:

function ajaxCall() { 
    //... some script to send ajax request which calls createDiv() after success
   if (window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
   }
   else{
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlhttp.onreadystatechange=function(){
      if(xmlhttp.readyState==4&&xmlhttp.status==200){
   


  •  Open
  •  27-07-2016
  •  4
  •  202

Answers ( 4 )

 Posted on 27-07-2016

The problem is that the code above is mixing appendChild with innerHTML. It's not intuitively obvious that the two perform differently in some cases. The former allows newly inserted script nodes to be executed as they are attached to the DOM. The latter doesn't. This has been a head-scratcher for many people. Kindly Google "script and innerHTML" and you will find that you are not alone facing this similar problem.

If you (1) change

_d.innerHTML = _jr + _vc + _rv
to

_d.appendChild(document.importNode(_jr));
_d.appendChild(document.importNode(_vc));
_d.appendChild(document.importNode(_rv));
and additionally (2) change

var _jr = dom.getElementById('script1').outerHTML;
var _vc = dom.getElementById('script2').outerHTML;
var _rv = dom.getElementById('script3').outerHTML;
to

var _jr = dom.getElementById('script1');
var _vc = dom.getElementById('script2');
var _rv = dom.getElementById('script3');
then your scripts will get executed. Here is a demonstration:

var b = document.getElementsByTagName('body')[0];

/* Works */
var s1 = document.createElement('script');
s1.innerHTML = "console.log('I will execute')";
b.appendChild(s1);

/* Fails */
var s2 = document.createElement('script');
s2.innerHTML = "while(1){alert('Do not worry! I will not execute');}";
b.innerHTML = s2.outerHTML;
console.log("It didn't execute");

 Posted on 27-07-2016

You are currently loading a script into your page. This happens AFTER the page js was already executed (since is async and usually loading an external resource takes longer than the script execution).

So... basically you have the right function definitions and everything, and calling them from console later should work (I think you already tried that and was fine).

Still, the calls to your functions, even thought they are there won't execute since will not be computed after load.

To work around this, you can create an ajax request to a page that has the script, and in its callback to call whatever function you need to call.

 Posted on 27-07-2016

The JavaScript of the page has already been parsed, you need to eval the result to put it into the window context.

function evalRequest(url) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            eval(xmlhttp.responseText);
        }
    }
    xmlhttp.open("GET", url, true);
    xmlhttp.send(null);
}; 

 Posted on 27-07-2016

I would say remove async, as the action comes after the initial page load