双向使用 MessageChannel() 用于页面和 iframe 之间的多条消息
Using MessageChannel() bidirectionally for multiple messages between page and iframe
我正在使用 MessageChannel() 在页面和 iframe 之间传递消息。在我的场景中,iframe 是通信发起者,包含它的页面接收、转换并响应回 iframe。
在我实施系统时,我首先获取并保存了对传递给 iframe 的端口的引用,将其缓存并继续在每次后续通信中使用它。
iframe:
window.onmessage = (e) => {
console.log("iframe port established");
//using this port for all following communications
parentPort = e.ports[0];
onmessage = establishedConnectionHandler;
}
我是 运行 从 iframe 通过 parentPort 到父级的所有后续通信:
parentPort.postMessage({command, guid, message});
尽管文档声明消息通道是一次性通信,但这似乎有效并使发起通信变得方便。
我的问题 - 这是支持的功能还是我在利用未定义的行为?
编辑 - 我一定是误解了示例的意图 MDN:
button.onclick = function(e) {
e.preventDefault();
var channel = new MessageChannel();
otherWindow.postMessage(textInput.value, '*', [channel.port2]);
channel.port1.onmessage = handleMessage;
function handleMessage(e) {
para.innerHTML = e.data;
textInput.value = '';
}
}
这在 Kaiido 的 Plunker 示例中进行了重构。
即使在 github 上阅读您的代码...
也不是很清楚您在做什么
您似乎混淆了 WindowObject.postMessage 方法和 MessagePort 方法。 WindowObject 的应该只使用一次,在协商部分。
因此,让我们退后一步,更基本地解释应该如何理解:
您应该将消息通道视为 Yoghurt-pot Telephone® [pdf]。
––––– –––––
po(r)t1 |~~~~~~~~~~~~~~~~~~~~~~~| po(r)t2
––––– –––––
- 一个用户必须创建它。
- 然后他将(transfer)其中一个点(r)ts给另一个用户。
- 完成此操作后,每个用户只能访问自己的 po(r)t。
- 因此,为了能够接收来自其他用户的消息,他们必须注意自己的 po(r)t(附加事件处理程序)。
- 并且要发送消息,他们会在他们仍然拥有的唯一 po(r)t 内说出消息 (postMessage),与他们正在收听的相同。
所以要添加一些代码行,你应该做的是:
生成 Yoghurt-pot telephone® a.k.a MessageChannel。
var yoghurt_phone = new MessageChannel();
保留其中一个 po(r)t,将另一个给其他用户 (iframe)。为此,我们使用 WindowObject.postMessage 方法,这与我们将用于通过 MessagePorts 进行通信的方法不同。
mains_yoghurt_pot = yoghurt_phone.port1;
frame.contentWindow.postMessage( // this is like a physical meeting
'look I made a cool Yoghurt-phone', // some useless message
'*', // show your id?
[yoghurt_phone.port2] // TRANSFER the po(r)t
);
从框架中,接收 po(r)t 并保持紧绷。
window.onmessage = function physicalMeeting(evt) {
if(evt.ports && evt.ports.length) { // only if we have been given a po(r)t
frames_yoghurt_pot = evt.ports[0];
// ...
从现在开始,每个用户都有自己的po(r)t,而且只有一个po(r)t。所以在两端,你需要在他们自己的单个 po(r)t 上设置监听器。
// from main doc
mains_yoghurt_pot.onmessage = frameTalksToMe;
// from iframe doc
frames_yoghurt_pot.onmessage = mainTalksToMe;
然后,当两个用户中的一个想要告诉另一个用户某事时,他们会根据 他们自己的 po(r)t 来做。
// from main doc
mains_yoghurt_pot.postMessage('hello frame');
// or from iframe doc
frames_yoghurt_pot.postMessage('hello main');
我正在使用 MessageChannel() 在页面和 iframe 之间传递消息。在我的场景中,iframe 是通信发起者,包含它的页面接收、转换并响应回 iframe。
在我实施系统时,我首先获取并保存了对传递给 iframe 的端口的引用,将其缓存并继续在每次后续通信中使用它。
iframe:
window.onmessage = (e) => {
console.log("iframe port established");
//using this port for all following communications
parentPort = e.ports[0];
onmessage = establishedConnectionHandler;
}
我是 运行 从 iframe 通过 parentPort 到父级的所有后续通信:
parentPort.postMessage({command, guid, message});
尽管文档声明消息通道是一次性通信,但这似乎有效并使发起通信变得方便。
我的问题 - 这是支持的功能还是我在利用未定义的行为?
编辑 - 我一定是误解了示例的意图 MDN:
button.onclick = function(e) {
e.preventDefault();
var channel = new MessageChannel();
otherWindow.postMessage(textInput.value, '*', [channel.port2]);
channel.port1.onmessage = handleMessage;
function handleMessage(e) {
para.innerHTML = e.data;
textInput.value = '';
}
}
这在 Kaiido 的 Plunker 示例中进行了重构。
即使在 github 上阅读您的代码...
也不是很清楚您在做什么您似乎混淆了 WindowObject.postMessage 方法和 MessagePort 方法。 WindowObject 的应该只使用一次,在协商部分。
因此,让我们退后一步,更基本地解释应该如何理解:
您应该将消息通道视为 Yoghurt-pot Telephone® [pdf]。
––––– –––––
po(r)t1 |~~~~~~~~~~~~~~~~~~~~~~~| po(r)t2
––––– –––––
- 一个用户必须创建它。
- 然后他将(transfer)其中一个点(r)ts给另一个用户。
- 完成此操作后,每个用户只能访问自己的 po(r)t。
- 因此,为了能够接收来自其他用户的消息,他们必须注意自己的 po(r)t(附加事件处理程序)。
- 并且要发送消息,他们会在他们仍然拥有的唯一 po(r)t 内说出消息 (postMessage),与他们正在收听的相同。
所以要添加一些代码行,你应该做的是:
生成 Yoghurt-pot telephone® a.k.a MessageChannel。
var yoghurt_phone = new MessageChannel();
保留其中一个 po(r)t,将另一个给其他用户 (iframe)。为此,我们使用 WindowObject.postMessage 方法,这与我们将用于通过 MessagePorts 进行通信的方法不同。
mains_yoghurt_pot = yoghurt_phone.port1; frame.contentWindow.postMessage( // this is like a physical meeting 'look I made a cool Yoghurt-phone', // some useless message '*', // show your id? [yoghurt_phone.port2] // TRANSFER the po(r)t );
从框架中,接收 po(r)t 并保持紧绷。
window.onmessage = function physicalMeeting(evt) { if(evt.ports && evt.ports.length) { // only if we have been given a po(r)t frames_yoghurt_pot = evt.ports[0]; // ...
从现在开始,每个用户都有自己的po(r)t,而且只有一个po(r)t。所以在两端,你需要在他们自己的单个 po(r)t 上设置监听器。
// from main doc mains_yoghurt_pot.onmessage = frameTalksToMe;
// from iframe doc frames_yoghurt_pot.onmessage = mainTalksToMe;
然后,当两个用户中的一个想要告诉另一个用户某事时,他们会根据 他们自己的 po(r)t 来做。
// from main doc mains_yoghurt_pot.postMessage('hello frame');
// or from iframe doc frames_yoghurt_pot.postMessage('hello main');