window.postMessage APIの使い方を調べた

postMessageとは

  • HTML5で拡張された機能
  • 任意のウィンドウへクロスオリジン通信が可能
  • セキュアである
  • 双方向の通信チャンネルが確立されてから通信を行う
    • 悪意あるWebサイトから知らないうちにされないようにしているため

使い方(送信)

win.postMessage("メッセージ", "http://www.example.com");

メッセージを受け取りたい対象に対してpostMessageを呼びます。 コードで示している win は以下を指します。

  • 自分のドキュメントウィンドウ内に生成されたiframe
  • JavaScriptで開いたポップアップウィンドウ
  • 自分のドキュメントウィンドウを含むウィンドウ
  • 自分のドキュメントを開いたウィンドウ

第一引数に渡したいメッセージ(文字列)、第二引数に宛先のオリジンを指定します。

受け取り方(受信)

addEventListenerを使って、messageイベントを登録します。

addEventListener('message', function(event) {
  // 受け取ってからの処理
}, false);

この event には、以下3つのプロパティが用意されています。

  • event.data
    • 実際のメッセージ内容(文字列)
  • event.origin
    • メッセージを送ってきたページの生成元
  • event.source
    • メッセージを送ってきた window オブジェクトの参照

セキュリティ上の注意点

postMessageの第二引数にワイルドカードを指定しない

postMessageの第二引数に '*' を指定すると、どのオリジンに対してもメッセージを送信することができるため、意図して使わない限り指定しないようにしたほうが良さそうです。

受け取ったメッセージの送信元を確認する

addEventListenerは送られてきたすべてのメッセージを受け取ることができるため、信頼できないページからのメッセージも受け取ることができます。 そのため、受け取ったら必ず以下のように信頼できる送信元であるかチェックをしたほうが良いです。

addEventListener('message', function(event) {
  if (event.origin !== 'http://www.example.com/') {
    return;
  }
}, false);

補足

最近は文字列でなくても良い

最新のブラウザではpostMessageの第一引数に、様々なデータオブジェクトを受け付けることができるようになっています。 ただ、IE8,IE9の場合はこの方法は使えないので、互換性を持たせたいのであればJSONを使うほうが良さそうです。 (もう、サポート切れているし意識しなくても良いかな。)

IE8以下は、addEventListener は使えないので attachEvent を使う

詳しくはこちら https://qiita.com/39_isao/items/506e08031adfca9a5933

参考