Chromeでlocalhost開発をしていて、別サイトと通信をする方法


開発状況

  • vue.jsでdevserverを使って、localhost開発をしている。
  • 開発しているSPA(ページA)が、別ウィンドウでページBを開いて、そちらとpostMessageで通信をしている。
  • 本番で動く場合は、ページAもページBも同一ドメインである。
  • 開発中は、ページAはLocalhostで、ページBが諸般の事情でインターネット上の開発サーバを利用する状況

開発中は以下のような感じです。

問題

同一ドメインの場合では問題ないのですが、開発環境ではドメインが違うので以下のようなエラーがでます。

Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.

ちなみに、ページAからページBを開いて、ページBから通信を待つのは、以下のようにしています。

      const win = window.open('http://example.com')
      // オープン先のサイトのロード時間があるので、1秒ほど待機をしてからイベントを設定する。
      setTimeout(() => {
        win.addEventListener('message', event => {
          const data = event.data
          if (data.command === 'close_page') {
            win.close()
          }
        }, false)
      },
      1000)

何をしているかというと、ページBを開いて、ページBで何かを作業して、処理が完了したら、ページBからpostMessageを送ってもらいます。ページAは、それを待ち受けて、ページBを閉じるというものです。

ここでは端折っていますが、ページBからページAに必要なデータも送ってもらっています。

解決法

まずは、以下を試しましたが、うまくいきませんでした。
クロスドメイン制約を回避するChromeショートカットを作る

でも、それなりにセキュリティレベルは落ちているし、開発用のChrome環境としてもよいので、これはこれで生かしておきます。

次に、Chromeの実験的な機能を操作できるフラグがあるということを、ソースは失念しましたが、見つけて、変更しました。

ChromeのURLに「chrome://flags/」を入力します。

下記のように「Disable site isolation」を「Disable」にしたらエラーがでなくなりました。

イベントリスナーが設定されているかを確認する

今回、addEventListenerで待ち受けているのですが、これをモニターする方法も探しました。
DevToolsのイベントの監視にあります。

みんながお世話になっている開発者ツールのコンソールで、「getEventListeners(window)」と入力すると、イベント一覧が取得できます。

今回は、「message」イベントを仕掛けているので、「messege」を開きます。
ここでは2個ありあした。その1個目の「lisner」を開くと、「FunctionLocation」が「」がでてきます。こいつになります。

なぜ1個目だとわかったかというと、同一ドメインでの場合と開発環境での場合で比較したからです。
エラーがでにく本番の場合で、イベントが効いてないようなら、こちらで調べてみてもいいかもしれません。

最後に

個人的に、「Disable site isolation」を「Disable」にしたら、「enable site isolation」で、ほんとにページ間通信ができないんじゃない!?って考えているのですが、まぁ、とりあえず、デバッグを進めたいので目をつむっておきます。

このあたり、Chromeのデバッグ関係の詳しい説明があれば嬉しいんですけど。。。。