別ウインドウで表示中の Web ページに対するクロスドメインスクリプト実行
Web ブラウザで別ウインドウ表示中の Web ページ(別ドメイン)のスクリプトを実行する方法を探ってみた。
セキュリティの関係上、Web ブラウザは別ドメインのページに対する DOM アクセスを許可しないため、通常の方法では実現できそうに無いが、セキュリティ設定を甘く(ActiveX コントロールの実行を許可等)した IE では、以下の方法で実施できる事が判明。
- WSH のシェルオブジェクト "Shell.Application" を使って script 要素を appendChild する
利用条件が限定的なため、あまり使い道は無さそうだが、イントラネット内の Web アプリケーション間の連携などで多少は使えるかと思う。
準備
とりあえず、スクリプト実行側の HTML ファイルを作成し、ローカルファイルを IE で直接開いておく。
file:///d:/cross_domain_script/called_script.html
<html> <head> <script type="text/javascript"> function test() { alert("別ウインドウからの実行"); } </script> </head> <body> </body> </html>
クロスドメインスクリプト実行
先ほどとは別の IE を立ち上げ以下のページを表示し(Web サーバー経由で取得)、"call script" ボタンを押下すると、called_script.html 側で test() が実行される。
処理内容は以下。
- Shell.Application オブジェクト生成
- ウインドウを列挙してスクリプト実行対象の IE を取得
- スクリプト実行対象 IE の document.body に script 要素を appendChild
http://localhost:8080/script_call.html
<html> <head> <script type="text/javascript"> function callScript() { try { var shell = new ActiveXObject("Shell.Application"); var appList = shell.Windows(); for (var i = 0; i < appList.Count; i++) { var app = appList.item(i); //app が取得できない場合があったため、まず app の存在確認 if (app && //IE の判定 app.FullName.match(/iexplore.exe$/i) && //スクリプト実行対象ページの判定 app.LocationName == "called_script.html") { //スクリプト要素の作成 var script = app.document.createElement("script"); script.type="text/javascript"; //スクリプトの処理内容を設定 script.text = "test();"; //called_script.html の body に script 要素を追加 app.document.body.appendChild(script); } } } catch (e) { alert(e.message); } } </script> </head> <body> <input type="button" onclick="callScript()" value="call script" /> </body> </html>