【问题标题】:postMessage() cross-origin iframe javascriptpostMessage() 跨域 iframe javascript
【发布时间】:2021-03-19 09:19:24
【问题描述】:

我正在尝试使用 postMessage() 与跨域资源通信,但无法使其正常工作。我已经查看了许多其他类似的问题,但仍然卡住了。

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessagehttps://javascript.info/cross-window-communicationHow can I do cross-domain postMessage? 等)

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

Uncaught DOMException: Blocked a frame with origin ... 无法访问 一个跨域框架。

我两次调用 postMessage()。使用通配符在页面加载后 - 这是有效的。并且一旦使用 delcared 来源 - 这是我需要的,但无法开始工作。

家长:

<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>

孩子:

<!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>

任何帮助将不胜感激!

【问题讨论】:

    标签: javascript iframe cross-domain postmessage


    【解决方案1】:

    看起来问题出在您的子脚本中,您正尝试访问 parent.originparent.location.host 导致错误,因为考虑到跨域问题,不允许这样做。

    如果您想从子代码中获取父域的域,您可以改用document.location.ancestorOrigins[0])。但是,目前 Firefox 似乎不支持此功能。见https://caniuse.com/?search=ancestorOrigin

    除此之外,其余的看起来还可以。

    这是一个关于如何从 iFrame 获取父域的选项的线程: Access parent URL from iframe

    【讨论】:

    • 谢谢 - postMessage 不只是关闭所有跨域保护措施。已实现的解决方案:捕获点击事件 => onclick="closeParentIframe(event);"。从中获得 origin => const pOrigin = clickEvent.view.location.origin
    猜你喜欢
    • 2014-07-01
    • 2011-11-23
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多