毎年数十年、数百年に一度の台風や災害が来るのは、時間の流れが過去よりも10倍〜100倍ぐらいになっているのかと、SFチックに考えてしまう下駄です。
この調子でいけば、10年後ぐらいには、毎年1000年に一度のミレニアム事象が多発してしまうのでは・・・
そんな自然災害よりも進化が早いプログラム言語では、仕様がどんどん更新されて、バージョンアップで別物になってしまうものも少なくありません。
javascriptもES6前と後で、別言語化してしまいましたが、下位互換に敏感な自分としてはどうしても新規バージョンに素直に移行できない現状があります・・・
ただし、新しい事を知らないという状態が怖いので、お勉強は続けていきますけどね。
そして最近「innerHTML」の代わりに「insertadjacenthtml」が便利に使いこなせてきたのですが、ブラウザのセキュリティ対策でscriptタグが実行できない問題は、innerHTMLから継承されているのかを調べてみました。
innerHTMLではscriptタグは実行されない問題
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>innerHTML</title>
</head>
<body>
<h1>innerHTML調査</h1>
<div id="inner"></div>
<script src="inner.js"></script>
</body>
</html>
var html = "Script : <script>alert('popup!!!');</script>";
var elm = document.getElementById("inner");
elm.innerHTML = html;
下記のtest.htmlとinner.jsを用意して、ブラウザで開いて実行してみると、以下のようになります。
innerHTMLでscriptタグが挿入されているのに、alertが実行されない。
これは、ajaxなどで、サイト側の意図しないscriptタグを自動実行されないようにしているセキュリティなのですが、以下のjsファイルを読み込んでみると・・・
alert('popup!!!');
これを、test.htmlを下記のように変更して読み込むと・・・
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>innerHTML</title>
</head>
<body>
<h1>innerHTML調査</h1>
<div id="inner"></div>
<script src="inner_2.js"></script>
</body>
</html>
alertは実行されました。
何がいいたいかと言うと、「ブラウザのセキュリティがあんまり意味をなしていないのではないか」ということ。
ではinnerHTMLでsrc属性付きのscriptタグを読み込むとどうなるでしょう?
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>innerHTML</title>
</head>
<body>
<h1>innerHTML調査</h1>
<div id="inner"></div>
<script>
document.getElementById("inner").innerHTML = "test :<"+"script src='inner_2.js'"+"><"+"/script"+">";
</script>
</body>
</html>
src属性も実行されないという事はscriptタグをinnerHTMLで文字列として読み込むだけで文字列としてしか認識せず、表示もなんもされないので無意味な命令になってしまいます。
これの解決方法は、DOMに読み込んだ後で、scriptタグをgetElementsByTagNameなどで取得して、scriptプログラムの文字列をevalしてあげるしか無いようです。
出来てしまうということはやはりこのセキュリティは意味がないという事にも感じますね。
insertAdjacentHTMLにおけるscriptタグの扱い
それでは、innerHTMLの後継機能でもあるinsertAdjacentHTMLでは同じことをやるとどうなるでしょう?
やはりscriptタグは文字列扱いなのでしょうか?
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>innerHTML</title>
</head>
<body>
<h1>innerHTML調査</h1>
<div id="inner"></div>
<script>
var html = "Script : <"+"script"+">alert('popup!!!');<"+"/script"+">";
var elm = document.getElementById("inner");
elm.insertAdjacentHTML("beforeend",html);
</script>
</body>
</html>
innerHTMLと全く同じですね・・・orz
とりあえず、今回はこれが分かれば十分なんですが、リファレンスページにはこうした事が書かれていないので検証してみただけでした。
参考ページ
https://developer.mozilla.org/ja/docs/Web/API/Element/insertAdjacentHTML
0 件のコメント:
コメントを投稿