window.postMessage方法并不总是调度消息

时间:2017-08-23 11:52:24

标签: javascript google-chrome-extension

我正在编写一个浏览器扩展程序,通过默认的消息传递接口完成大部分通信,例如chrome扩展帖子连接“postMessage”和safari,“tab.dispatchMessage”。

但是我有一些简单的消息,有助于识别顶部框架内的子框架元素,我不想将它们发送到后台脚本,我不想纯粹使用标准的window.postMessage方法。

问题是内框并不总是从顶部框架发送消息。 (当我向内框发送消息时,我几乎可以确定它已被加载)。

所以基本上我的问题是如何做到这一点,以及如何确保我的来自顶部框架的消息到达内部框架。

编辑:最小代码示例

// SCRIPT WHICH IS RUNNING IN INNER FRAME
// this is where the algorithm starts 
var uuid = "unique generated id";

// STEP 4
// this is where the message send via frames[i].contentWindow.postMessage
// should be received, and this is where the problem is (it's not received sometimes, or to be more clear, not received on some pages)
window.addEventListener("message", function (event) {
    var message = JSON.parse(event.data);
    if (message.uuid === uuid) {
        event.source.postMessage(event.data, "*");
    }
});

// STEP 1
// send identifier to top frame letting it know that inner frame
// loaded and needs to be mapped
window.top.postMessage(JSON.stringify({uuid: uuid}), "*");

-

// SCRIPT WHICH IS RUNNING IN TOP FRAME
// this script is loaded before inner frame thus is able 
// receive messages from inner frames all the time

var frames = document.getElementsByTagName("iframe");
var callMap = {}, frameMap = {};

// STEP 2
window.addEventListener("message", function (event) {
    var message = JSON.parse(event.data);

    // when inner frame send message with uuid but with ack
    // it needs to be mapped, the sending inner frame uuid 
    // will be sent to all frames with additional (ack) id
    if (message.uuid && !message.ack) {
        callMap[message.uuid] = {};
        for (var i = 0, len = frames.length; i < len; i++) {
            var ack = "another unique id";
            callMap[message.uuid][ack] = frames[i];
            // STEP 3
            frames[i].contentWindow.postMessage(JSON.stringify({
                uuid: message.uuid, ack: ack
            }), "*");
        }
    }

    if (message.ack) {
        frameMap[message.uuid] = callMap[message.uuid][message.ack];
        delete callMap[message.uuid];
    }
});

0 个答案:

没有答案