クロスドメインメッセージング完全に理解した

はじめに

クロスドメインメッセージングとは、その名の通り異なるドメイン間でデータをやり取りする方法です。 これを実現するためにはiframeを使わないといけないらしいんですが、既存の説明ではいまいち納得行かなかったので自分なりに解釈してまとめました。

iframeを使う理由

f:id:gakki-uec15:20191007013253p:plain
クロスドメインメッセージングでiframeを使う理由

1. クロスドメイン制約

jsがサイトS1とS2、両方にアクセスできるのは明らかにダメです。S1のデータがjs経由でS2に流れてしまいますからね。

なのでS1のjs(js1)はS1だけに、S2のjs(js2)はS2だけにアクセスできるようにしました。これがクロスドメイン制約です。

2. postMessaging

1.でjs1とjs2を完全に分離したけど、js2が「データほしい!」(request)と言って、js1が「いいよ!!」(response)と言ったときは通信できてもいいですよね? なのでpostMessagingという通信手段ができました。これは、あるドメインからあるドメインにrequestを送って、相手が良ければresponseを返す、というものです。

3. iframe

2.で通信手段ができたけど、まだjs2はjs1にrequestを送れません。なぜなら今の状態ではjs2はjs1の居場所がわからないからです。 ドメインを指定してあげても、javascriptとして参照できるのは同じwindowのオブジェクトだけだからです。

そこでjs2はjs1を自分のwindowにiframeとして召喚します。 そうするとjs2はjs1がiframeにいることが分かり、お願い(request)ができるようになるわけです。

request側(js2側)

<!DOCTYPE html>
<html>

<head>
    <title>js2</title>
    <meta charset="utf-8">
</head>

<body>

    <iframe id="ifm" src="http://localhost:8001" width="500" height="100"></iframe>

    <script>
        // Send Request
        window.onload = function(){
            var ifm = document.getElementById("ifm").contentWindow;
            ifm.postMessage("Request Message", "http://localhost:8001");    // ifm にあるlocalhost8001に対してrequest
        }

        // Listen Response
        window.addEventListener("message", function(event){
            console.log(event);
        }, false);

    </script>

    <p>This is launched in localhost:8000</p>

</body>

</html>

response側(js1側)

<!DOCTYPE html>
<html>

<head>
    <title>js1</title>
    <meta charset="utf-8">
</head>

<body>

    <script>
        window.addEventListener("message", function(event){
            console.log(event)
            event.source.postMessage("Response Message", event.origin)  // あくまでこのメッセージしか渡さない(保存してる変数全部見えるとかない)
        }, false)
    </script>

    <p>This is launched in localhost:8001</p>

</body>

</html>

まとめ

クロスドメインメッセージング完全に理解した。

参考文献

https://tsmatz.wordpress.com/2011/06/24/jsonp-cross-domain/ https://qiita.com/yasumodev/items/d339a875b4b9bf65d156 https://developer.mozilla.org/ja/docs/Web/API/Window/postMessage