Edited at

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


開発状況


  • vue.jsでdevserverを使って、localhost開発をしている。

  • 開発しているSPA(ページA)が、別ウィンドウでページBを開いて、そちらとpostMessageで通信をしている。

  • 本番で動く場合は、ページAもページBも同一ドメインである。

  • 開発中は、ページAはLocalhostで、ページBが諸般の事情でインターネット上の開発サーバを利用する状況

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

fig1.png


問題

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

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

2019-02-21_19h32_06.png

ちなみに、ページ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」にしたらエラーがでなくなりました。

2019-02-21_19h42_25.png


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

今回、addEventListenerで待ち受けているのですが、これをモニターする方法も探しました。

DevToolsのイベントの監視にあります。

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

今回は、「message」イベントを仕掛けているので、「messege」を開きます。

ここでは2個ありあした。その1個目の「lisner」を開くと、「FunctionLocation」が「」がでてきます。こいつになります。

image.png

なぜ1個目だとわかったかというと、同一ドメインでの場合と開発環境での場合で比較したからです。

エラーがでにく本番の場合で、イベントが効いてないようなら、こちらで調べてみてもいいかもしれません。


最後に

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

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