跨域iframe通信

15

我有一个在页面上创建的 iframe,页面的域名被明确设置为 "xyz.com",但是 iframe 的域名默认为 "dev.xyz.com",这是我正在开发的实际域名。

问题是,当我尝试通过 iframe.contentWindow.document 访问该 iframe 时,由于域名的差异而失败。

我已经尝试将 iframe 的 src 设置为一个文件,并将 document.domain 设置为 "xyz.com",但似乎没有效果...

有什么想法吗?


我认为您需要将iframe的document.domain和主页面的document.domain都设置为相同的内容。(更多信息请参见此处 - Alconja
作为进一步的跟进,这里是创建iframe并尝试访问它的代码:jQuery("body").prepend('<iframe id="jQuery_history" style="display: none;"'+' src="javascript:false;"></iframe>');var ihistory = jQuery("#jQuery_history")[0]; var iframe = ihistory.contentWindow.document; - Chris
由于您可以访问父窗口和 iframe,我建议阅读以下内容:http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/ - Kyle Cureau
Ben Alman有一个很棒的jQuery插件,可以用来解决这个问题。http://benalman.com/projects/jquery-postmessage-plugin/ - Justin
1
这个库支持HTML5 postMessage和具有resize+hash的旧版浏览器 https://github.com/ternarylabs/porthole(Ben Alman的jQuery插件已经3年没有更新了) - jpillora
你可以使用这个库 https://github.com/mdx-dev/inception 进行一些握手操作。 - Rulian
3个回答

12

1
这个不太正规的方法会干扰 Access-Control-Allow-Origin 请求,例如从 JS 中加载的 CDNs 的 AJAX 加载。在使用时要小心。 - Farside

8

经过一些研究,我找到了这个jQuery插件,它使用各种技巧使postMessage与旧浏览器兼容。

下面是一个快速示例,展示了如何将iframe的body高度发送给父窗口:

在主机(父)页面上:

    // executes when a message is received from the iframe, to adjust 
    // the iframe's height
    $.receiveMessage(
        function( event ){
            $( 'my_iframe' ).css({
                height: event.data
            });
    });
   // Please note this function could also verify event.origin and other security-related checks.

在 iframe 页面上:
$(function(){

    // Sends a message to the parent window to tell it the height of the 
    // iframe's body        
    var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);

    $.postMessage(
        $('body').outerHeight( true ) + 'px',
        '*',
        target
    );

});

我已经在XP和W7上的Chrome 13+、Firefox 3.6+、IE7、8和9以及OSX和W7上的Safari上进行了测试。;)

0
作为对Ben Alman插件的参考补充,我想发布这个可行的示例。它依赖于一个包含jQuery身份验证和数据查询脚本的iframe,然后使用消息插件将结果传递给{其他域}父窗口。
注意:如果使用JQ v9,则消息插件会中断,因为JQV9不使用插件中引用的“browser”。
第一步:将插件代码添加到发送和接收文档中:

http://benalman.com/projects/jquery-postmessage-plugin/

第二步: 将此内容添加到发送文档中:

   $.postMessage(
$(X).html(),    
'http://DOMAIN [PORT]/FOLDER/SUBFOLDER/RECIEVINGDOCNAME.XXX'   
 )  ;      

X 可以是包含预格式化 JSON 数组或其他内容的本地变量,这里的 HTTP URL 是接收文档的地址。

第三步: 将此添加到接收文档中:

    $.receiveMessage(
    function(event){
        alert("event.data: "+event.data);
                $("#testresults").append('<h1>'+event.data+'<h1>');

    },          
    'http://DOMAIN.COM OR SOMETHING'

);

其中http url是发送文档的域名。

在IE 8、9、FF16、safari Windows(windows wait x V9尚未测试)、safari x mac thing中表现良好。

结果是您想要从另一个域页面中获取的任何项目(只要您有访问权限..)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接