post消息给出"Blocked frame"错误,但仅在Safari中



我正在使用postMessage在https://www.example.com(我称之为mainSite(和https://subdomain.example.com(我称之为subSite(

subSite有一个iframe到mainSite,

subSite的代码看起来像:

//set the src of the iframe
$("#main-site-iframe").attr("src", "https://www.example.com");
//wait for the main site page to open
$("#main-site-iframe")[0].onload = () => {
//my page posts a message to their site
$("#my-iframe")[0].contentWindow.postMessage("messagePlox", "https://www.example.com");  
};
//wait for the iframe to message back
window.addEventListener('message', iframeResponse, false);
function iframeResponse(e) {
//make sure the request is from the correct site
if(e.origin == 'https://www.example.com')
{
//Got the data
console.log(e.data);
}
}

mainSite看起来像这样:

//listen for the subdomain to make a request
window.addEventListener('message', subdomainRequest, false);
function subdomainRequest(e) {
//make sure the request is from the correct subdomain
if(e.origin == 'https://subdomain.example.com')
{
//respond with the data
e.source.postMessage("We got you", e.origin);
}
}

上面的问题是,除了Safari拒绝它并说:之外,它在所有浏览器中都能工作

阻止了具有原点的帧"https://www.example.com"从访问具有原点的帧"https://subdomain.example.com".协议、域和端口必须匹配。

这似乎意味着由于mainSite正试图"访问"subSite,因此响应正在中断。

有人知道为什么这种情况只会发生在Safari中,而不会发生在Firefox或Chrome中吗?

双向跨域iFrame通信通常在Safari/Opera中被阻止。解决这一问题的主要方法是使用父母和孩子都同意的网关……但他们不能使用IPC使用无网络消息进行双向通信。或者,Nitro JS引擎团队也会密切关注一些例外情况,如果你有一个大的iFrame,并且用户正在与它交互,那么来自父级的消息就会通过,反之亦然。

来自父级的消息会像在软件中一样被处理。。。也就是说,不要期望在处理程序中正常工作。。。测试很多。例如,由于某种原因,无法从消息处理函数调用我的promise解析函数。。。这意味着我必须检查函数是否在一段时间内被调用,这让事情变得非常缓慢。

如果你只需要展示孩子的成功信息,你可以这样做:

parent.sendSuccessMsg();
function sendSuccessMsg(){
document.getElementById('iframeID').src="http://example.com/?successData=123";
}

否则,您可以使用带有网关的websocket来跨域混合。如果您两次加载iFrame,并且消息是在iFrame加载的早期发送的,那么似乎会出现某种未记录的异常。

来源:https://benohead.com/blog/2015/12/07/cross-document-communication-with-iframes/Bug/Failsafe发现:如何在safari中发送跨域邮件?