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