在onmessage事件处理程序中是否有标准的方法来识别自己的postMessage?

Dir*_*oer 5 javascript postmessage

我有一个基于iframe的小部件,它使用postMessage与父级进行通信.这意味着即我从iframe发送消息以请求调整其自身的大小.数据是json,目前正在干扰父页面上其他小部件/脚本发送的消息.

所以我需要一种方法来区分我自己的消息和其他消息.

现在我正在考虑简单地添加一个{ app: 'Poules.com', [...] }参数并在处理消息之前检查该参数.

但在此之前:是否已经有任何已建立的合同?

发送代码:

parent.postMessage( JSON.stringify(data), page.widgetOrigin );
Run Code Online (Sandbox Code Playgroud)

接收结束:

poules.sdk.receiveMessage = function(event)
{
    var data = JSON.parse( event.data );

    switch ( data.message )
    {
        case 'requestResize':   poules.sdk.requestResize( data ); break;
        case 'loginSuccess':    poules.sdk.triggerLoginEvent( data ); break;
        default: throw "poules.sdk: can't parse message: " + event.data;
    };
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 4

当您收到message事件时,您必须检查event.origin以确保它来自您想要接收消息的来源。这通常足以将它们与其他消息区分开来。

所以:

poules.sdk.receiveMessage = function(event)
{
    if (event.origin != "http://poules.com") { // or whatever
        return;
    }

    var data = JSON.parse( event.data );

    switch ( data.message )
    {
        case 'requestResize':   poules.sdk.requestResize( data ); break;
        case 'loginSuccess':    poules.sdk.triggerLoginEvent( data ); break;
        default: throw "poules.sdk: can't parse message: " + event.data;
    };
}
Run Code Online (Sandbox Code Playgroud)

这有两个原因:

  1. 它会过滤掉来自与您正在执行的操作无关的窗口的消息,并且

  2. 它会过滤掉试图冒充您的小部件并欺骗主页做不应该做的事情的恶意消息

event.origin有关MDN 的更多信息;这是关于如何形成字符串的注释:

起源

postMessage调用了当时发送消息的窗口的起源。该字符串是协议和“://”(主机名(如果存在))和“:”(如果存在端口且与给定协议的默认端口不同)后跟端口号的串联。典型来源的示例包括https://example.org(暗示端口 443)、http://example.net(暗示端口 80)和http://example.com:8080。请注意,不能保证此原点是该窗口的当前或未来原点,该窗口可能已被导航到不同的位置,因为postMessage被调用。