--- title: Channel Messaging の使用 slug: Web/API/Channel_Messaging_API/Using_channel_messaging tags: - API - Channel messaging - HTML5 - MessageChannel - MessagePort - Tutorial translation_of: Web/API/Channel_Messaging_API/Using_channel_messaging ---
{{DefaultAPISidebar("Channel Messaging API")}}
Channel Messaging API(チャンネルメッセージング API)を使用すると、同じドキュメントに添付された異なる閲覧コンテキストで実行される2つの別々のスクリプト(2つの IFrame、メインドキュメントと IFrame、{{domxref("SharedWorker")}} を介した2つのドキュメントなど)で直接通信し、両端にポートを持つ双方向チャンネル(またはパイプ)を介して相互にメッセージをやり取りできます。
この記事では、このテクノロジーを使用するための基本を探ります。
{{AvailableInWorkers}}
チャンネルメッセージングは、ゲーム、アドレス帳、または音楽を個人用に選択したオーディオプレーヤーなど、IFrame を介して他のサイトの機能をメインインターフェイスに埋め込むソーシャルサイトがある場合に主に役立ちます。 これらが独立したユニットとして機能する場合は問題ありませんが、メインサイトと IFrame、または異なる IFrame との間のやり取りが必要な場合は困難になります。 例えば、メインサイトからアドレス帳に連絡先を追加したり、メインプロファイルにゲームのハイスコアを追加したり、オーディオプレーヤーからゲームに新しい BGM の選択肢を追加したりする場合はどうすればよいのでしょうか。 ウェブが使用するセキュリティモデルのため、このようなことは従来のウェブテクノロジーを使用したのでは、それほど簡単ではありません。 オリジンがお互いを信頼しているかどうか、そしてメッセージをどのように渡すのかについて考えなければなりません。
一方、メッセージチャンネルは、異なる閲覧コンテキスト間でデータを受け渡すことを可能にする安全なチャンネルを提供することができます。
注: 詳細情報とアイデアについては、仕様のウェブ上のオブジェクト機能モデルの基礎としてのポート(英語)のセクションが役に立つでしょう。
はじめに、Github でいくつかのデモを公開しました。 最初に、ページと埋め込まれた {{htmlelement("iframe")}} の間の非常に単純な単一メッセージ転送を示す、チャンネルメッセージングの基本的なデモをチェックしてください(それをライブでも実行してください)。
次に、メインページと IFrame の間で複数のメッセージを送信できる、もう少し複雑な設定を示す、マルチメッセージデモを見てください(これをライブで実行)。
ここでは、マルチメッセージデモに焦点を当てます。 それは次のような感じです。
デモのメインページには、{{htmlelement("iframe")}} に送信するメッセージを入力するためのテキスト入力を含む単純なフォームがあります。 また、{{htmlelement("iframe")}} から返される確認メッセージを表示するために後で使用する段落もあります。
var input = document.getElementById('message-input'); var output = document.getElementById('message-output'); var button = document.querySelector('button'); var iframe = document.querySelector('iframe'); var channel = new MessageChannel(); var port1 = channel.port1; // Wait for the iframe to load // iframe が読み込まれるのを待ちます iframe.addEventListener("load", onLoad); function onLoad() { // Listen for button clicks // ボタンのクリックをリッスンする button.addEventListener('click', onClick); // Listen for messages on port1 // port1 でメッセージをリッスンする port1.onmessage = onMessage; // Transfer port2 to the iframe // port2 を iframe に移管する iframe.contentWindow.postMessage('init', '*', [channel.port2]); } // Post a message on port1 when the button is clicked // ボタンがクリックされたときに port1 にメッセージを投稿する function onClick(e) { e.preventDefault(); port1.postMessage(input.value); } // Handle messages received on port1 // port1 で受信したメッセージを処理する function onMessage(e) { output.innerHTML = e.data; input.value = ''; }
まず {{domxref( "MessageChannel.MessageChannel","MessageChannel()")}} コンストラクタを使用して新しいメッセージチャンネルを作成します。
IFrame が読み込まれたら、ボタン用の onclick
ハンドラと {{domxref("MessageChannel.port1")}} 用の onmessage
ハンドラを登録します。 最後に、{{domxref("window.postMessage")}} メソッドを使って {{domxref("MessageChannel.port2")}} を IFrame に移管します。
iframe.contentWindow.postMessage
行の機能をもう少し詳しく調べてみましょう。 これは次の3つの引数を取ります。
'init'
に設定しています。*
は「任意のオリジン」を意味します。ボタンをクリックすると、フォームを通常のように送信せず、テキスト入力に入力された値は {{domxref("MessageChannel")}} を介して IFrame に送信します。
IFrame では、次の JavaScript があります。
var list = document.querySelector('ul'); var port2; // Listen for the intial port transfer message // 初期ポート移管メッセージをリッスンする window.addEventListener('message', initPort); // Setup the transfered port // 移管されたポートを設定する function initPort(e) { port2 = e.ports[0]; port2.onmessage = onMessage; } // Handle messages received on port2 // port2 で受信したメッセージを処理する function onMessage(e) { var listItem = document.createElement('li'); listItem.textContent = e.data; list.appendChild(listItem); port2.postMessage('Message received by IFrame: "' + e.data + '"'); }
初期メッセージを {{domxref("window.postMessage")}} メソッドを介してメインページから受信すると、initPort
関数が実行されます。 これは移管されたポートを保存し、メッセージが {{domxref("MessageChannel")}} を通過するたびに呼び出される onmessage
ハンドラを登録します。
メインページからメッセージを受信したら、リスト項目を作成し、それを順序なしリストに挿入し、リスト項目の {{domxref("Node.textContent","textContent")}} をイベントの data
属性と同じ値に設定します(これは実際のメッセージを含みます)。
次に、最初に IFrame に移管された {{domxref("MessageChannel.port2")}} で {{domxref("MessagePort.postMessage")}} を呼び出して、確認メッセージをメッセージチャンネル経由でメインページに投稿します。
メインページに戻って、onmessage
ハンドラ関数を見ましょう。
// Handle messages received on port1 // port1 で受信したメッセージを処理する function onMessage(e) { output.innerHTML = e.data; input.value = ''; }
元のメッセージが正常に受信されたことを確認するメッセージが IFrame から返されると、これは単に確認を段落に出力し、テキスト入力を空にして次のメッセージの送信の準備をします。
仕様 | 状態 | コメント |
---|---|---|
{{SpecName('HTML WHATWG', 'web-messaging.html#channel-messaging', 'Channel messaging')}} | {{Spec2('HTML WHATWG')}} |
MessageChannel
{{Compat("api.MessageChannel", 0)}}
MessagePort
{{Compat("api.MessagePort", 0)}}