Javascript script execution in innerHTML
February 23rd, 2006
I am developing a new website for a club I’m founding. I can’t tell you what this club will do (also because I don’t really know, yet) but the site is going to become a challenge.
I wanted to use all the latest, innovative technologies around here. So, I just took PHP, Javascript, XHTML (strictly 1.0 strict!) and a MySQL database in my gunnysack and gone around with them.
There’s an issue I’ve been facing against that just got me crazy: if I include a HTML page (not really, a php generated one to be precise) through innerHTML the content that was into the <script>...</script> tags was not executed. After some google-ing, I found that this is a security implementation: browsers doesn’t allow code to be executed into a innerHTML block. If you break a moment and think about it, it makes perfectly sense, but I need of such a feature so I had to found a workaround.
The idea was this: let threat the html page as an xml file (although it is really one), so let use the DOM to browse it looking for <script></script>, then pass its content to eval().
I was not using any AJAX library, so I had to wrote all the code by myself. Here is a snippet:
function execJS(node) {
var bSaf = (navigator.userAgent.indexOf('Safari') != -1);
var bOpera = (navigator.userAgent.indexOf('Opera') != -1);
var bMoz = (navigator.appName == 'Netscape');
var st = node.getElementsByTagName('SCRIPT');
var strExec;
for(var i=0;i<st.length; i++) {
if (bSaf) {
strExec = st[i].innerHTML;
} else if (bOpera) {
strExec = st[i].text;
} else if (bMoz) {
strExec = st[i].textContent;
} else {
strExec = st[i].text;
}
try {
eval(strExec);
} catch(e) {
alert(e);
}
}
}
function handlePageChanging()
{
if (http.readyState == 4) {
var cnt_big = document.getElementById('cnt_big');
cnt_big.innerHTML = http.responseText;
execJS(cnt_big);
hideLoading();
doLinks();
}
}
function changeContentPage(param)
{
_current = param;
var url = param + '&aJ=y';
showLoading();
http.open("GET", url, true);
http.onreadystatechange = handlePageChanging;
http.send(null);
}
Of course you can’t copy and paste this code except the execJS function (since it is this post’s purpose) but the important thing is that you notice how it works. Pratically, the page makes an AJAX request with changeContentPage(), then handle it through handlePageChanging(). So when we’re going to set up the content with innerHTML, we call execJS() so it will eval()-ize all the <script></script> contents.
Update: see this http://kratcode.blogspot.com/2006/03/javascript-script-execution-in.html
[…] The execJS() I posted some time ago have some problems (and it, yes, was just a modify to the AHAH version). I didn’t really realized what exactly it is, but I found a simple (?) solution. The problem, as far as I can understand, is that eval() doesn’t always execute the code. So here it is the workaround: look for <script> tags, take its content and create a new element into the <head> with createElement/appendChild. In this way we should also be more standard-compliant than before: […]
Pingback by Javascript script execution in innerHTML: the revenge « kratorius::code — October 1st, 2006 at 17:53
Neat script! Can I see some basic examples of this? I’m trying to insert a div (with innerHTML) with script tags in it that contains a function that loads in an swf. The SWFObject to be more exact http://blog.deconcept.com/swfobject/. Is that possible you think?
Cheers
Mike
Comment by mike — May 31st, 2007 at 8:22