双向Javascript window.postMessage - 调度订单问题

时间:2015-01-14 21:13:06

标签: javascript iframe xss postmessage

postMessage可用于在Windows之间发送消息,通常是从iframe发送到父级或父级发送到iframe。

postMessage仅在一个方向上发送数据并且是不符合要求的 - 与函数调用不同,函数调用从调用返回值并在线执行(后者是前者的条件)。 / p>

为了将信息发送回"来电者","被叫"必须自己做postMessage

现在让我们假设我想测试一个合适的监听器是否存在:我将根据某些约定postMessage,如果监听器存在,它将postMessage回来。

我能在什么时候确定没有听众?我该如何实施等待?

我试过 - 在IE11,Chrome和Firefox上 - 以下实验:

  1. postMessage iframe的窗口会在收到消息后立即回复
  2. postMessage 自己的窗口,作为在事件处理中调度未来点的方法
  3. 以下是这些步骤的代码:

    var iframe = document.getElementById('iframe');
    iframe.contentWindow.postMessage('hello', '*');
    window.postMessage('schedule', '*')
    

    iframe的响应代码是:

    window.addEventListener('message', function (event) {
        window.top.postMessage('echo ' + event.data, '*');
    }, false);
    

    父窗口的监听器本身是这样的:

    var n = 0;
    window.addEventListener("message", function (event) {
        if (n > 4) return;
        console.info(event.data);
        window.postMessage('(repeat of ' + event.data + ' #' + n + ')', '*')
        n++;
    }, false);
    

    总之,我不断重新调度事件,以便记录队列的性质。

    在IE11,Chrome和Firefox上,这会(反复):

    schedule <-- shouldn't make the mistake to believe there's no listener yet!
    echo hello
    (repeat of schedule #0)
    (repeat of echo hello #1)
    (repeat of (repeat of schedule #0) #2)
    

    我可以猜测&#34;为什么会这样:浏览器有一个消息队列,并将前两个消息(&#34; hello&#34;然后&#34; schedule&#34;)放入。这些消息将在任何预定的消息之前处理后来。特别是,iframe的答案将安排在处理&#34;你好&#34;消息,然后将在&#34; schedule&#34;之后处理。消息。

    因此,要确定是否有听众,必须发布&#34;时间表&#34;消息在自己的窗口上,然后是另一个&#34;重复的时间表#0&#34;来自该事件处理的消息。

    仅在处理此间接&#34;重复计划#0&#34;消息仍然没有来自iframe的消息,我们可以肯定没有听众。

    哇,对于这样一个简单的问题,这是一个复杂的解决方案。

    我的问题是:是否有任何保证浏览器有一个公共消息队列,以便以这种方式真正调度事件?

    当然,有一种更简单的方法仍然可靠吗? (别忘了考虑计时器!)

0 个答案:

没有答案