【特集】
HTML5から、ウィンドウ(フレーム)間でメッセージの送受信を行うための仕組みが用意された。この仕組みを用いると、対象となるウィンドウのインスタンスさえ手に入れば、同じオリジン(プロトコル+ドメイン + ポート番号)のWebページはもちろん、違うオリジンのWebページとも通信を行うことが可能だ。
まず、他のウィンドウから送られてきたメッセージを受信するには、windowオブジェクトのmessageイベントを監視する必要がある。
// messageイベントの監視
window.addEventListener("message", function() {...}, false);
他のウィンドウに対してメッセージを送信する場合は、window.postMessage()メソッドを使用する。
postMessage(data, "targetOrigin");
postMessage()の第1引数は送信するメッセージ本文で、任意のJavaScriptオブジェクトを指定することができる。
第2引数は対象となるウィンドウのオリジンURLを文字列で指定する(例: "http://localhost:8080/")。これが実際のウィンドウのオリジンと一致していなければ、メッセージの送信に失敗する。ここには「すべてのサイト」を表す"*"(アスタリスク)を指定する事も可能だが、悪意のあるWebサイトに対して不用意にメッセージを送信してしまわないよう、既知のURLをできる限り指定したほうがよい。
以上の知識があれば、ウィンドウ間でメッセージを送受信することができる。実際のサンプルを見てみよう。
このサンプルは、iframe内のページとメッセージの送受信を行うものだ。
また、ページ自体はlocalhostの80番ポートで動作するWebサーバに配置したが、iframe内のページは「http://localhost:8080」がオリジンとなっており、クロスオリジンのデータ送受信を実現している。
サンプルのソースコードを以下に示す。まずはメインページだ。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
// (1) messageイベントを監視
window.addEventListener("message", function(ev) {
// (2) 既知のオリジンからのメッセージ以外は無視
if (ev.origin != "http://localhost:8080") {
return;
}
// (3) データの表示
alert(ev.origin + "からのメッセージを受信しました:\n「" + ev.data + "」");
}, false);
function hello() {
var iframe = window.frames[0];
// (4) メッセージの送信
iframe.postMessage("こんにちは", "http://localhost:8080/");
}
</script>
</head>
<body>
<h1>クロスドキュメントメッセージングのテスト</h1>
<iframe width="400" src="http://localhost:8080/frame.html" onload="hello()">
</iframe>
</body>
</html>
次に示すのはiframe内に表示するページのソースコードだ。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
window.addEventListener("message", function(ev) {
if (ev.origin != "http://localhost") {
alert(ev.origin);
return;
}
document.body.innerHTML = ev.origin + "からのメッセージを受信しました:<br>「" + ev.data + "」";
// (5) メインページに対してメッセージ送信
ev.source.postMessage("こんにちは。こちらは" + this.location + "です。", ev.origin);
}, false);
</script>
</head>
<body></body>
</html>
このサンプルにおけるポイントを以下に示す。
(1) windowオブジェクトのmessageイベントを監視することで、メッセージの受信を行える。
(2) messageイベントのoriginプロパティにアクセスすると、メッセージ送信元のオリジンを取得することができる(この例では「http://localhost:8080」が返る)。悪意のあるページからのメッセージを処理しないためにも、オリジンのチェックは必須だ。
(3) messageイベントのdataプロパティにアクセスすると、メッセージ本文(任意のJavaScriptオブジェクト)を取得することができる。
(4) メッセージの送信にはpostMessage()を使用する。
(5) messageイベントのsourceプロパティにアクセスすると、メッセージ送信元のwindowオブジェクト(正確にはWindowProxy)を取得することができる。
このサンプルは、Firefox3.5、Safari4、Chrome3、Opera10での動作を確認した。
| マイナビ、3月より書籍連動型のクリエイティブ・デザイン系セミナー開講 [12:00 2/10] |
| Linux Mint 12 KDE登場 [10:26 2/10] |
| Dell、重複排除により最大98%のデータ削減が可能なバックアップストレージを発売 [09:44 2/10] |
| 北大、「ポジトロン断層撮影法」による脳腫瘍の性質を診断する手法を開発 [09:40 2/10] |
| NICTなど、手術支援ロボット「da Vinci」の3D裸眼映像伝送実証実験を計画 [09:36 2/10] |
|
松嶋菜々子登場に「ミタ」パパ・長谷川博己パニック - 鈴木京香との熱愛は? [12:03 2/10] エンタメ |
|
【コラム】奥様はコマガール 第31回 30代既婚男性たちの妻への本音 [12:00 2/10] ライフ |
|
マイナビ、3月より書籍連動型のクリエイティブ・デザイン系セミナー開講 [12:00 2/10] エンタープライズ |
|
【レポート】CP+2012 - ビジュアルのクオリティと新しいアクセス手段を追求 - ソニー [11:52 2/10] 家電 |
|
「SBIポイント」が「Suicaポイント」とポイント交換提携サービスを開始 [11:50 2/10] ライフ |