FireFox3でappendChildを使ってscriptタグを追加すると、スクリプトが実行される。
昨日のサンプルコードを書くときに気になってちょっと試していたのだけど、innerHTMLでscriptタグを挿入しても実行されないみたいだなー。(FireFox3とIE7では)。あれ、じゃYUIのGetUtilityはどうやってるんだろう、と思っていろいろ試してみるとappendChild()を使ってhead要素に追加するとスクリプトが実行されるようだ(FireFox3、IE7とも)。さらに、FireFox3ではhead要素以外の適当なdivにappendChild()してもスクリプトが実行される。
操作 | IE7 | FireFox3 |
---|---|---|
innerHTMLでscriptタグを挿入 | 実行されない | 実行されない |
innerHTMLでsrc属性を持つscriptタグを挿入 | 実行されない | 実行されない |
appendChildでscriptタグをheadに挿入 | 実行される | 実行される |
appendChildでscriptタグを適当なタグに挿入 | 実行されない | 実行される |
検証で使用したコードはこちら。ソースは以下のとおりです。
index.html :
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="insert.js"></script> </head> <body> <ul> <li><a href="javascript:insert();">innerHTMLでscriptタグを挿入 →スクリプトは実行されない。</a></li> <li><a href="javascript:insert2();">innerHTMLでsrc属性を持つscriptタグを挿入 →スクリプトは実行されない。</a></li> <li><a href="javascript:insert3();">appendChildでscriptタグをheadに挿入 →スクリプトが実行される</a></li> <li><a href="javascript:insert4();">appendChildでscriptタグを適当なタグに挿入 →<b>FireFox3ではスクリプトが実行される。IE7では実行されない。</b></a></li> </ul> <div id="out"> </div> </body> </html>
insert.js :
// innerHTMLでscriptタグを挿入 // →スクリプトは実行されない。 function insert() { var str = '<script type="text/javascript">alert("スクリプトが実行されました");</script>'; document.getElementById("out").innerHTML = str; } //innerHTMLでsrc属性を持つscriptタグを挿入 // →スクリプトは実行されない。 function insert2() { var str = '<script type="text/javascript" src="alert.js" /></script>'; document.getElementById("out").innerHTML = str; } // appendChildでscriptタグをheadに挿入 // →スクリプトが実行される。 function insert3() { var n = document.createElement("script"); n.setAttribute( "type", "text/javascript"); n.setAttribute( "src", "alert.js"); document.getElementsByTagName("head")[0].appendChild( n ); } //appendChildでscriptタグを適当なタグに挿入 // →FireFox3ではスクリプトが実行される。 function insert4() { var str = '<script type="text/javascript">alert("スクリプトが実行されました");</script>'; var n = document.createElement("div"); n.innerHTML = str; document.getElementById("out").appendChild( n ); }
alert.js :
alert("スクリプトが実行されました");
appendChild()とかあんまし使わないよー、とかいう場合でも「insert4()」のように「innerHTMLで中身を作った要素をappendChildで追加」とかやってたりしそう。(この場合もスクリプトは実行されてしまいます。)まぁ、なんにしても信頼できない文字列を挿入する際は気をつけないといけないなということですかね。