【问题标题】:How to use JavaScript to access cross domain iFrame content?如何使用 JavaScript 访问跨域 iFrame 内容?
【发布时间】:2011-02-06 10:12:11
【问题描述】:

我想使用这个代码

window.parent.document.getElementById('message').value  += "\r\n\r\n[img]"+response+"[/img]";

它适用于来自同一域的页面,但不适用于加载到 iFrame 中的另一个域的站点。我该怎么做?

【问题讨论】:

标签: javascript iframe cross-domain


【解决方案1】:

您可以实现 window.postMessage 以跨域跨 iframe/windows 进行通信。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>

    <!--
    <link rel="shortcut icon" href="/favicon.ico">


    <link rel="start" href="http://benalman.com/" title="Home">

    <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">

    <script type="text/javascript" src="/js/mt.js"></script>
    -->
    <script type="text/javascript">
        // What browsers support the window.postMessage call now?
        // IE8 does not allow postMessage across windows/tabs
        // FF3+, IE8+, Chrome, Safari(5?), Opera10+

        function SendMessage()
        {
            var win = document.getElementById("ifrmChild").contentWindow;

            // http://robertnyman.com/2010/03/18/postmessage-in-html5-to-send-messages-between-windows-and-iframes/


            // http://stackoverflow.com/questions/16072902/dom-exception-12-for-window-postmessage
            // Specify origin. Should be a domain or a wildcard "*"

            if (win == null || !window['postMessage'])
                alert("oh crap");
            else
                win.postMessage("hello", "*");
            //alert("lol");
        }



        function ReceiveMessage(evt) {
            var message;
            //if (evt.origin !== "http://robertnyman.com")
            if (false) {
                message = 'You ("' + evt.origin + '") are not worthy';
            }
            else {
                message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
            }

            var ta = document.getElementById("taRecvMessage");
            if (ta == null)
                alert(message);
            else
                document.getElementById("taRecvMessage").innerHTML = message;

            //evt.source.postMessage("thanks, got it ;)", event.origin);
        } // End Function ReceiveMessage




        if (!window['postMessage'])
            alert("oh crap");
        else {
            if (window.addEventListener) {
                //alert("standards-compliant");
                // For standards-compliant web browsers (ie9+)
                window.addEventListener("message", ReceiveMessage, false);
            }
            else {
                //alert("not standards-compliant (ie8)");
                window.attachEvent("onmessage", ReceiveMessage);
            }
        }
    </script>


</head>
<body>

    <iframe id="ifrmChild" src="child.htm" frameborder="0" width="500" height="200" ></iframe>
    <br />


    <input type="button" value="Test" onclick="SendMessage();" />

</body>
</html>

Child.htm

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>

    <!--
    <link rel="shortcut icon" href="/favicon.ico">


    <link rel="start" href="http://benalman.com/" title="Home">

    <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">

    <script type="text/javascript" src="/js/mt.js"></script>
    -->

    <script type="text/javascript">
        /*
        // Opera 9 supports document.postMessage() 
        // document is wrong
        window.addEventListener("message", function (e) {
            //document.getElementById("test").textContent = ;
            alert(
                e.domain + " said: " + e.data
                );
        }, false);
        */

        // https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage
        // http://ejohn.org/blog/cross-window-messaging/
        // http://benalman.com/projects/jquery-postmessage-plugin/
        // http://benalman.com/code/projects/jquery-postmessage/docs/files/jquery-ba-postmessage-js.html

        // .data – A string holding the message passed from the other window.
        // .domain (origin?) – The domain name of the window that sent the message.
        // .uri – The full URI for the window that sent the message.
        // .source – A reference to the window object of the window that sent the message.
        function ReceiveMessage(evt) {
            var message;
            //if (evt.origin !== "http://robertnyman.com")
            if(false)
            {
                message = 'You ("' + evt.origin + '") are not worthy';
            }
            else
            {
                message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
            }

            //alert(evt.source.location.href)

            var ta = document.getElementById("taRecvMessage");
            if(ta == null)
                alert(message);
            else
                document.getElementById("taRecvMessage").innerHTML = message;

            // http://javascript.info/tutorial/cross-window-messaging-with-postmessage
            //evt.source.postMessage("thanks, got it", evt.origin);
            evt.source.postMessage("thanks, got it", "*");
        } // End Function ReceiveMessage




        if (!window['postMessage'])
            alert("oh crap");
        else {
            if (window.addEventListener) {
                //alert("standards-compliant");
                // For standards-compliant web browsers (ie9+)
                window.addEventListener("message", ReceiveMessage, false);
            }
            else {
                //alert("not standards-compliant (ie8)");
                window.attachEvent("onmessage", ReceiveMessage);
            }
        }
    </script>


</head>
<body style="background-color: gray;">
    <h1>Test</h1>

    <textarea id="taRecvMessage" rows="20" cols="20" ></textarea>

</body>
</html>

【讨论】:

    【解决方案2】:

    看看easyXDM,它是一个易于使用的库,它为用于启用跨域消息传递的多种技巧提供了统一的 API,从 postMessage 到 FIM 技巧作为最后的手段。
    这是 Twitter 和 Disqus 等主要服务所使用的内容。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
    • @DavidePastore - 这是一个非常复杂的问题,而且问题过于开放,无法提供简洁的答案。
    【解决方案3】:

    由于same origin policy 的限制,这是不允许的。

    【讨论】:

      【解决方案4】:

      如上所述,这属于同源策略,但有一些技巧可以限制与 iframe 的通信。看看http://ajaxify.com/run/crossframe/

      【讨论】:

      • 这里使用的片段破解非常慢并且有很多问题 - easyXDM 是一种更好的方法。
      【解决方案5】:

      如果您的浏览器禁用了安全功能,您可以使用 chrome

      "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security
      

      更新:我很惊讶人们一直致力于它,因为他们认为它有害,所以在这里我为那些不了解网络安全基础但仍在尝试开发它的人们添加一些额外的细节。

      如果

      ,请勿使用此解决方案
      • 您正在使用不受您信任的 chrome 插件或应用,或者

      • 你在chrome中打开过其他网站,或者

      • 你有一些恶意的 chrome 进程

      • 您的网站正在使用任何外部资源。

      要使此解决方案完全安全,请将防火墙配置为阻止所有连接,但您正在建立 CORS 连接的连接除外。

      此外,如果您的连接端点不受信任,请勿使用此解决方案。

      【讨论】:

      • 我认为这是非常有害的,强烈建议不要使用这种方法。
      • @Nicky 如果您知道自己在做什么,它是无害的。但是感谢您的通知,我已经为那些可能会毫无头绪地尝试使用此解决方案的人添加了免责声明。
      【解决方案6】:

      你不能。这称为同源策略,可防止 javascript 跨域访问内容。

      【讨论】:

        猜你喜欢
        • 2014-03-16
        • 2014-08-02
        • 2011-12-09
        • 2021-09-06
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多