postMessage()跨源iframe javascript

postMessage()跨源iframe javascript,javascript,iframe,cross-domain,postmessage,Javascript,Iframe,Cross Domain,Postmessage,我正在尝试使用postMessage()与跨来源资源通信,但无法使其正常工作。我已经复习了几十个其他类似的问题,但仍然被卡住了 (、等) 我在同一个原点上工作,但是当我移动到另一个原点时,我会得到一个标准的corss原点错误 未捕获的DomeException:阻止了具有原点的帧。。。从访问 交叉原点框架 我调用postMessage()两次。一旦进入页面,使用通配符加载-这是有效的。一旦使用了Delcare origin,这就是我所需要的,但无法开始工作 家长: <html>

我正在尝试使用postMessage()与跨来源资源通信,但无法使其正常工作。我已经复习了几十个其他类似的问题,但仍然被卡住了

(、等)

我在同一个原点上工作,但是当我移动到另一个原点时,我会得到一个标准的corss原点错误

未捕获的DomeException:阻止了具有原点的帧。。。从访问 交叉原点框架

我调用postMessage()两次。一旦进入页面,使用通配符加载-这是有效的。一旦使用了Delcare origin,这就是我所需要的,但无法开始工作

家长:

<html>
    <body>
        <button class="site-btn" onclick="initChatIfr();">Load Iframe</button>
        <iframe lws-ifr="demo-ifr" lws-ifr-status='inactive'></iframe>
    <script>
        const ifrEle = document.querySelector('[lws-ifr="chat-ifr"]');
        function initChatIfr() {
            ifrEle.src = 'https://some-cdn.cloudfront.net/post-message/index.html';
            ifrEle.setAttribute('lws-ifr-status', 'active');
        }

        function listener(e) {
            const acceptedOrigins = ['https://some-cdn.cloudfront.net', 'https://some-sandbox.s3.amazonaws.com', 'http://localhost:3000'];
            
            if (e.data.indexOf('close') < 0 || acceptedOrigins.indexOf(e.origin) < 0) {
                console.log('   not a close event or an unapproved ifr origin')
                return;
            } else {
                console.log(' approved ifr origin')
                ifrEle.setAttribute('lws-ifr-status', 'inactive');
                setTimeout(function() {
                    ifrEle.src = '';
                },300);                    
            }
        }

        if (window.addEventListener){
            addEventListener("message", listener, false);
        } else {
            attachEvent("onmessage", listener);
        }
    </script>
    </body>
</html>

加载Iframe
const ifrEle=document.querySelector('[lws ifr=“chat ifr”]');
函数initChatIfr(){
ifrEle.src=https://some-cdn.cloudfront.net/post-message/index.html';
ifrEle.setAttribute('lws-ifr-status','active');
}
函数侦听器(e){
const acceptedOrigins=['https://some-cdn.cloudfront.net', 'https://some-sandbox.s3.amazonaws.com', 'http://localhost:3000'];
if(e.data.indexOf('close')<0 | | acceptedOrigins.indexOf(e.origin)<0){
console.log('不是关闭事件或未经批准的ifr来源')
返回;
}否则{
console.log('approved ifr origin')
ifrEle.setAttribute('lws-ifr-status','inactive');
setTimeout(函数(){
ifrEle.src='';
},300);                    
}
}
if(window.addEventListener){
addEventListener(“消息”,侦听器,false);
}否则{
attachEvent(“onmessage”,listener);
}
儿童:

<!DOCTYPE html>
<html>
<body>
    <button class="site-btn cancel-btn" onclick="closeParentIframe();">Close Iframe</button>
    <script>
        const acceptedHosts = ['some-cf-cdn.cloudfront.net', 'some-sandbox-bucket.s3.amazonaws.com', 'localhost:3000'];
        function closeParentIframe() {
            const pOrigin = parent.origin;
            const pHost = parent.location.host;
            if (acceptedHosts.indexOf(pHost) > -1) {
                console.log(' APPROVED parent origin', pOrigin);
                parent.postMessage('close', pOrigin);
            } else {
                console.log(' UNAPPROVED parent origin', pOrigin);
            }
        }
        console.log('ifr loaded');
        parent.postMessage("hi from the ifr " + location.href, '*');
     </script>
</body>
</html>

关闭Iframe
const acceptedHosts=['some-cf-cdn.cloudfront.net','some sandbox bucket.s3.amazonaws.com','localhost:3000'];
函数closeParentIframe(){
const pOrigin=parent.origin;
const pHost=parent.location.host;
if(acceptedHosts.indexOf(pHost)>-1){
控制台日志(‘批准的父源’,pOrigin);
parent.postMessage('close',pOrigin);
}否则{
console.log('未经批准的父源',pOrigin);
}
}
console.log('ifr-loaded');
postMessage(“来自ifr的hi”+location.href,”*);

任何帮助都将不胜感激

看起来问题出在您的子脚本中,您正在尝试访问
父.origin
以及
父.location.host
,这是导致错误的原因,因为考虑到跨源问题,不允许访问

如果要从子代码中获取父域,可以改用
document.location.ancestorOrigins[0])
。然而,Firefox似乎目前不支持这种功能。看

除此之外,其余的看起来都不错

下面是一个关于如何从iFrame获取父域的选项的线程:

谢谢-postMessage不仅仅是关闭所有跨源保护。实现的解决方案:捕获单击事件=>onclick=“closeParentIframe(事件);”。从中获取origin=>const pOrigin=clickEvent.view.location.origin