The Channel Messaging API allows two separate scripts running in different browsing contexts attached to the same.
This API allows two scripts in different browser contexts to communicate and pass messages to each other in a two-way channel.
The different browser contexts can be two scripts running in different tabs, two iframes in a script, the document and an iframe in a script, etc.
It begins with creating a MessageChannel
instance:
new MessageChannel()
This will return a MessagePort
object.
Then, each browser context can set up port using MessagePort.port1
or MessageChannel.port2
.
The context that instantiated the MessageChannel
will use MessagePort.port1
, while the other context will use MessagePort.port2
.
Then, messages can be communicated using the postMessage
API.
Each browser context will then listen to messages using the Message.onmessage
.
Let’s see a simple example, where we can use MessageChannel
to send text between a document and an iframe.
<body>
<header>
<h2>Web APIs<h2>
</header>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Demo - MessageChannel
</div>
<div class="web-api-card-body">
<div id="error" class="close"></div>
<div id="displayMsg">
</div>
<div>
<input id="input" type="text" placeholder="Send message to iframe" />
</div>
<div>
<button onclick="sendMsg()">Send Msg</button>
</div>
<div>
<iframe id="iframe" src="./iframe.content.html"></iframe>
</div>
</div>
</div>
</div>
</body>
<script>
try {
var channel = new MessageChannel()
var port1 = channel.port1
} catch(e) {
error.innerHTML = "MessageChannel API not supported in this device."
error.classList.remove("close")
}
iframe.addEventListener("load", onLoad)
function onLoad() {
port1.onmessage = onMessage
iframe.contentWindow.postMessage("load", channel.port2)
}
function onMessage(e) {
const newHTML = "<div>"+e.data+"</div>"
displayMsg.innerHTML = displayMsg.innerHTML + newHTML
}
function sendMsg() {
iframe.contentWindow.postMessage(input.value, channel.port2)
}
</script>
Notice the iframe tag. We loaded an iframe.content.html
file on it. The button and text are where we type and send a message to the iframe.
<script>
const channel = new MessageChannel()
const port1 = channel.port1
iframe.addEventListener("load", onLoad)
function onLoad() {
port1.onmessage = onMessage
iframe.contentWindow.postMessage("load", channel.port2)
}
function onMessage(e) {
const newHTML = "<div>"+e.data+"</div>"
displayMsg.innerHTML = displayMsg.innerHTML + newHTML
}
function sendMsg() {
iframe.contentWindow.postMessage(input.value, channel.port2)
}
</script>
We initialized the MessageChannel
and the port1
. We added a load event listener to the iframe. Here we register the onmessage
listener on the port1
, then send a message to the iframe using the postMessage
API. See that the channel port2
is sent down to the iframe.
Let’s look at the iframe’s iframe.content.html
:
<body>
<div class="web-api-cnt">
<div class="web-api-card">
<div class="web-api-card-head">
Running inside an <i>iframe</i>
</div>
<div class="web-api-card-body">
<div id="iframeDisplayMsg">
</div>
<div>
<input placeholder="Type message.." id="iframeInput" />
</div>
<div>
<button onclick="sendMsgiframe()">Send Msg from <i>iframe</i></button>
</div>
</div>
</div>
</div>
</body>
<script>
var port2
const l = console.log
window.addEventListener("message", function(e) {
l(e)
port2 = e.ports[0]
port2.onmessage = onMessage
})
function onMessage(e) {
const newHTML = "<div>"+e.data+"</div>"
iframeDisplayMsg.innerHTML = iframeDisplayMsg.innerHTML + newHTML
}
function sendMsgiframe(){
port2.postMessage(iframeInput.value)
}
</script>
Here, we register a message event handler. We retrieve port2
and set an onmessage
event handler on it. Now, we can receive and send a message from the iframe to its parent document.
RELATED TAGS
CONTRIBUTOR
View all Courses