チャネルメッセージングAPI

Channel Messaging APIを使用すると、iframeとワーカーはメッセージを渡すことでメインドキュメントスレッドと通信できます。

Channel MessagingAPIの概要

同じドキュメントで実行されているがコンテキストが異なる2つのスクリプトがある場合、Channel Messaging APIを使用すると、チャネルを介してメッセージを渡すことで通信できます。

このユースケースには、

  • ドキュメントとiframe
  • 2つのiframe
  • 2つのドキュメント

使い方

呼び出しnew MessageChannel()メッセージチャネルが初期化されます。

const channel = new MessageChannel()

チャネルには、と呼ばれる2つのプロパティがあります

  • ポート1
  • ポート2

これらのプロパティはMessagePortオブジェクトです。port1チャネルを作成したパーツによって使用されるポートであり、port2はチャネル受信者が使用するポートです(ちなみに、チャネルは双方向なので、受信者はメッセージを送り返すこともできます)。

チャネルの両端で、一方のポートでリッスンし、もう一方のポートにメッセージを送信します。

メッセージの送信は、

otherWindow.postMessage()

メソッド、ここでotherWindow他のブラウジングコンテキストです。

メッセージ、発信元、およびポートを受け入れます。

例えば:

const data = { name: 'Flavio' }
const channel = new MessageChannel()
window.postMessage(data, [channel.port2])

メッセージには、サポートされている値のいずれかを指定できます。

「オリジン」はURIです(例:https://example.org)。使用できます'*'厳密性の低いチェックを許可する、ドメインを指定する、または指定する'/'どのドメインであるかを指定せずに、同じドメインのターゲットを設定します。

他のブラウジングコンテキストは、を使用してメッセージをリッスンしますmessageイベント:

self.addEventListener('message', event => {
  console.log('A new message arrived!')
})

self使用するのと同じですwindowこの場合

イベントハンドラー内で、送信されたデータにアクセスできます。dataイベントオブジェクトのプロパティ:

self.addEventListener('message', event => {
  console.log('A new message arrived!')
  console.log(event.data)
})

を使用して返信できますMessagePort.postMessage

self.addEventListener('message', event => {
  console.log('A new message arrived!')
  console.log(event.data)

const data = { someData: ‘hey’ } event.ports[0].postMessage(data) })

チャネルを閉じるには、close()ポートのメソッド:。

self.addEventListener('message', event => {
  console.log('A new message arrived!')
  console.log(event.data)

const data = { someData: ‘hey’ } event.ports[0].postMessage(data) event.ports[0].close() })

iframeの例

これは、ドキュメントとの間で発生する通信の例です。iframeそれに埋め込まれています。

メインドキュメントは、iframespanから送信されたメッセージを印刷しますiframe資料。すぐにiframeドキュメントが読み込まれ、メッセージを送信しますchannel作成しました。

<!DOCTYPE html>
<html>
  <body>
    <iframe src="iframe.html" width="500" height="500"></iframe>
    <span></span>
  </body>
  <script>
    const channel = new MessageChannel()
    const display = document.querySelector('span')
    const iframe = document.querySelector('iframe')
<span style="color:#a6e22e">iframe</span>.<span style="color:#a6e22e">addEventListener</span>(<span style="color:#e6db74">'load'</span>, () =&gt; {
  <span style="color:#a6e22e">iframe</span>.<span style="color:#a6e22e">contentWindow</span>.<span style="color:#a6e22e">postMessage</span>(<span style="color:#e6db74">'Hey'</span>, <span style="color:#e6db74">'*'</span>, [<span style="color:#a6e22e">channel</span>.<span style="color:#a6e22e">port2</span>])
}, <span style="color:#66d9ef">false</span>)

<span style="color:#a6e22e">channel</span>.<span style="color:#a6e22e">port1</span>.<span style="color:#a6e22e">onmessage</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">event</span> =&gt; {
  <span style="color:#a6e22e">display</span>.<span style="color:#a6e22e">innerHTML</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">event</span>.<span style="color:#a6e22e">data</span>
}

</script> </html>

iframeページのソースはさらに単純です。

<!DOCTYPE html>
<html>
  <script>
  window.addEventListener('message', event => {
    // send a message back
    event.ports[0].postMessage('Message back from the iframe')
  }, false)
  </script>
</html>

ご覧のとおり、チャネルを初期化する必要はありません。window.onmessageコンテナページからメッセージを受信すると、ハンドラが自動的に実行されます。

送信されるイベントは、次のプロパティで構成されます。

  • data:他のウィンドウから送信されたオブジェクト
  • origin:メッセージを送信したウィンドウの元のURI
  • source:メッセージを送信したウィンドウオブジェクト

メッセージ送信者の発信元を常に確認してください。

e.ports[0]私たちが参照する方法ですport2iframeで、なぜならportsは配列であり、ポートは最初の要素として追加されました。

サービスワーカーの例

Service Workerは、イベント駆動型ワーカーであり、Webページに関連付けられたJavaScriptファイルです。チェックしてくださいサービスワーカーガイドそれらについてもっと知るために。

知っておくべき重要なことは、Service Workerはメインスレッドから分離されており、メッセージを使用してそれらと通信する必要があるということです。

これは、メインドキュメントに添付されたスクリプトがServiceWorkerへのメッセージの送信を処理する方法です。

// `worker` is the service worker already instantiated

const messageChannel = new MessageChannel()
messageChannel.port1.addEventListener('message', event => {
  console.log(event.data)
})
worker.postMessage(data, [messageChannel.port2])

Service Workerコードでは、のイベントリスナーを追加しますmessageイベント:

self.addEventListener('message', event => {
  console.log(event.data)
})

そしてそれはにメッセージを投稿することによってメッセージを送り返すことができますmessageChannel.port2、と

self.addEventListener('message', event => {
  event.ports[0].postMessage(data)
})

ブラウザのサポート

Channel Messaging APIは現在、すべての主要なブラウザでサポートされており、その多くは長い間サポートされているため、古いバージョンでもサポートされています。のすべての詳細をチェックしてくださいhttps://caniuse.com/#feat=channel-messaging

私の無料ダウンロードJavaScriptビギナーズハンドブック


その他のブラウザチュートリアル: