4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】同一オリジン間ではwindow.postMessage()ではなくBroadcastChannelを使う

Posted at

ブラウザのウィンドウ間でメッセージをやりとりする方法はwindow.postMessage()を使う方法が有名ですが、もう一つBroadcastChannelというものを使った方法もあります。二者の特徴をまとめたのが以下です。

  • window.postMessage()
    • 異なるオリジン間でメッセージの送受信が可能
    • 送信相手のwindowへの参照が必要
  • BroadcastChannel
    • 同一オリジン間でしかメッセージの送受信ができない
    • 送信相手への参照が必要がない

ということで同一オリジンのウィンドウ間のメッセージのやりとりはBroadcastChannelを使うべきです。他のサイトはメッセージを受信することができないのでセキュリティ的に好ましいですし、開発者としても送信相手へのwindow参照を持つ必要がなく実装が単純になります。逆にオリジンを跨ぐ場合はwindow.postMessage()を使うしかないということになります。

ちなみにBroadcastChannelは主要なブラウザ全てでサポート済みです。

使用方法

BroadcastChannelにはチャンネルという概念があり、あるチャンネルに送られたメッセージは同じチャンネルでしか受信されません。チャンネルはBroadcastChannelのコンストラクタにチャンネル名を与えることで指定します。以下の例ではチャンネル名としてchannelNameを指定しています。

使い方は非常にシンプルです。

送信方法

const channel = new BroadcastChannel('channelName');
channel.postMessage(message);

messageは送信するメッセージです。messageとして送れる型の制約は正確に述べると複雑ですが、少なくともJSONと対応する型は送れます。オブジェクトや配列をネストした複合型でもOKです。

受信方法

const channel = new BroadcastChannel('channelName');
channel.addEventListener('message', ev => {
  const message = ev.data;
});

上記コードによりchannel.postMessage(message)で送信したメッセージが変数messageとして受信されます。

以上!

補足: 同一オリジンとは?

補足としてここでいう「同一オリジン」の意味を説明します。ここでいう「オリジン」とは簡単に言えばスクリプトが動いているブラウザのアドレスバーに表示されているURLのホスト名より前側(ポートがあるならポートより前側)の部分のことです。

まず一般にオリジンとはプロトコル、ホスト名、ポート番号の組のことです。例えばhttp://example.com:8080/path.htmlというURLのオリジンはhttp://example.com:8080です。

そしてここでいうオリジンがなんのオリジンかというと、閲覧コンテキストのオリジンと説明できます。閲覧コンテキストのオリジンとは先程の通り簡単に言えばブラウザのアドレスバーのURLのオリジンです。スクリプトファイル自体のURLではありません。 つまり例えば以下のHTMLページがhttps://www.example.com/index.htmlとして表示されている場合、その<script>タグのスクリプトの閲覧コンテキストはスクリプトファイルのURLのオリジンであるhttps://other.domain.net ではなく https://www.example.comです。

https://www.example.com/index.html
<!DOCTYPE html>
<html>
  <head>
    <script src="https://other.domain.net/index.js"></script>
  </head>
  <body>
  </body>
</html>

以上で説明したオリジンが同じスクリプト同士ではBroadcastChannelで通信できるということです。

あとがき

window.postMessage()は前から知ってたけどBroadcastChannelは最近知ったので、みんな知らないんじゃね?と勝手に思って書いた記事。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?