読者です 読者をやめる 読者になる 読者になる

window.postMessage()の学習

javascript

javascriptのwindow間のメッセージングについて、存在は知っていたけどちゃんとコードとして落とし込めていなかったので学習。

参照先は以下の2サイト

window.postMessage

他のwindowに対して、messageを送る。 => window.postMessage();
windowを超えてクロスドメインでアクセスしようとすると、permission deniedになったり、undefinedになったりするけど、postMessageは有効に使える。

引数は第2引数まで取る。(第2引数まで必須。)

otherWindow.postMessage(message, targetOrigin)
otherWindow
送信対象のwindow
message
送信するメッセージ。String。Objectを贈ろうとすると怒られる。送ろうと思えば、セキュアじゃないけどCookieの値も送れる。
targetOrigin
送信先のOriginの指定。"*"で無指定にするか、URLで指定する。

送信したmessageは、onmessageイベントで受け取ることができる。
受け取ったときのhandlerに渡されるオブジェクトから、送信元のオリジンやメッセージを引き出せる。

サンプル

参照先のサイトを元に(ほとんど同じだけど)サンプル。

今回は、parent windowから、iframeで別ドメインのサイトを呼び出し、iframeのwindowからparent windowにメッセージを送る

parent window

domain: http://hoge.example/post_message.html

<html>
  <head>
  </head>
  <body>
    <script type='text/javascript'>
      window.addEventListener(
        "load",
        function(e) {
          console.log("parent loaded");
        },
        false
      );
      window.addEventListener(
        'message',
        function(e) {
          console.log("message received");
          if (e.origin == 'http://fuga.example') {
            console.log(e.data);
          }
        },
        false
      );
    </script>
    <iframe src="http://fuga.example/post_message.html"></iframe>
  </body>
</html>
iframe window

domain: http://fuga.example/post_message.html

<html>
  <head>
    <script type="text/javascript">
      window.addEventListener(
        "load",
        function(e) {
          console.log("iframe loaded");

          // parent.document: for Opera compatibility
          var target = (parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined));

          if (typeof target != 'undefined') {
            target.postMessage('from fuga to hoge', '*')
            console.log("post message from iframe");
          }
        },
        false
      );
    </script>
  </head>
  <body>
  </body>
</html>

まとめ

クロスドメインなサイトでのJS操作では覚えておきたい知識。
IEの対応をちゃんと見ていないけど、onmessageイベントが、古いIEだと未対応?