我正在与JS的postMessage方法建立跨域通信。嵌入式 iframe 正在发送消息,父窗口正在接收消息。问题是,即使在 receivedMessage 中检查了来源(这减少了大量收到的消息数量),我仍然收到两条消息,一条是我发布的,另一条是很久以前为不同目的而写的。因此,我无法真正修改此其他(不需要的)消息的postMessage方法。就此而言,在postMessage方法或receiveMessage中是否有一种方法可以帮助识别哪一个是我的?也许我在这里缺少一些额外的参数或配置?
postMessage 的代码(在嵌入式 iframe 中):
window.parent.postMessage("Hello world!", "*");
接收消息的代码(在父窗口中):
window.addEventListener("message", receiveMessage, false);
function receiveMessage(e) {
var reliableHost = "://" + "<%= Site.current_site.internal_admin_host %>";
var secureHost = "https" + reliableHost;
var notSecureHost = "http" + reliableHost;
if (e.origin.indexOf(secureHost) != -1 || e.origin.indexOf(notSecureHost) != -1) {
var data = e.data;
console.log(data);
console.log(e.source);
// filter the other event
}
}
由于 data
参数完全在您的控制之下,并且可以是一个对象,因此您可以使用 data 参数中的约定来确保只处理您关心的消息。另请注意,indexOf(...) != -1
可能不太正确,您可能希望改用indexOf(...) == 0
(或startsWith
),以避免字符串后面的匹配。
所以在收到时(见***
行[你必须用SO的显示屏向右滚动]):
window.addEventListener("message", receiveMessage, false);
function receiveMessage(e) {
var reliableHost = "://" + "<%= Site.current_site.internal_admin_host %>";
var secureHost = "https" + reliableHost;
var notSecureHost = "http" + reliableHost;
if ( (e.origin.indexOf(secureHost) == 0 || e.origin.startsWith(notSecureHost) == 0) && // ***
(e.data && e.data.type === "whatever") // ***
) { // ***
var payload = e.data.payload; // ***
console.log(payload); // ***
console.log(e.source);
// filter the other event
}
}
发送时:
postMessage({type: "whatever", payload: /*...*/});
我总是使用具有不同type
值的这种机制,以便与同一整体页面/应用程序进行不同通信的通信渠道相互干扰。
是的:而不是传入字符串,例如 "Hello world!"
,而是传入一个对象,并针对该对象执行检查。您可以先检查e.data
是否typeof object
,然后检查对象具有哪些属性。您可以设置任何类型的自定义属性,以允许您标识感兴趣的帖子消息。例如,iframe 可以执行以下行:
window.parent.postMessage({
source: 'my-custom-app',
message: 'Hello world!'
}, '*');
然后在收到帖子消息时,您可以简单地检查是否:
- 发布消息有效负载(即
data
参数)是一个对象,并且 - 发布消息有效负载包含密钥
source
,其值为my-custom-app
父页面上的示例代码:
window.addEventListener("message", receiveMessage, false);
function receiveMessage(e) {
var reliableHost = "://" + "<%= Site.current_site.internal_admin_host %>";
var secureHost = "https" + reliableHost;
var notSecureHost = "http" + reliableHost;
// Guard clause to catch unwanted messages from other hosts
if (e.origin.indexOf(secureHost) === -1 && e.origin.indexOf(notSecureHost) === -1)
return;
var data = e.data;
if (typeof data === 'object' && data.source === 'my-custom-app') {
// Filtered event handling here
}
}