zoukankan      html  css  js  c++  java
  • 由iframe而引发的一系列思考(跨域通信)

    前情提要:公司的首页,有三个板块需要自定义,故以iframe开发的形式给到第三方,第三方只要提供url给到父页面,即可实现板块的随意定制,并与父页面部分脱离(一定程度上还不能完全脱离父页面的联系,下文会细说)

    问题起因:iframe的高度由子页面的高度决定,即子页面撑起iframe的高度,非iframe定宽,适用子页面内容动态不固定的情况,此场景需要获取子页面的高度,动态赋值iframe的height

           情况一:父页面的地址与iframe的地址origin相同,即协议、域名、端口相同,此情况不存在跨域问题,可直接操作dom   

    // 同源非跨域,父级页面获取子级页面的高度赋值iframe
    function setIframeHeight(id){
        try{
            var iframe = document.getElementById(id);
            if(iframe.attachEvent){
                iframe.attachEvent("onload", function(){ 
                    iframe.height =  iframe.contentWindow.document.documentElement.scrollHeight; // iframe.contentWindow,获取iframe的window对象
                });
                return;
            }else{
                iframe.onload = function(){
                    iframe.height = iframe.contentDocument.body.scrollHeight; // iframe.contentDocument, 获取iframe的document对象
                };
                return;                 
            }     
        }catch(e){
            throw new Error('setIframeHeight Error');
        }
    }

           情况二:父页面与子页面的url地址,存在部分域相同,即aaa.xxx.com与bbb.xxx.com二级域名相同,但浏览器同源限制,父子页面相互dom操作,会跨域   

    需要将父子两个页面都设置domain,如:document.domain = "xxx.com",这样两个页面就可以操作了,实现了同一基础域名的跨域,设置domain后获取高度的方案就可以用上述同源非跨域的解决方案。 利用document.domain实现跨域的前提条件:这两个域名必须属于同一个基础域名(必须包含一个‘.’号),且所用的协议,端口都要一致

           情况三:父页面与子页面的url地址,完全不相同,则可以使用CDM(cross document message)实现跨文本文档、多窗口、跨域消息传递,该方法兼容相ie8+

     发送消息:targetWindow.postMessage(message,targetOrigin,[transfer]);

                    targetWindow指要接受消息的窗口;

                    message需要传递的消息内容,通常是字符串,若是对象,需要JSON.stringify转化

                    targetOrigin接受消息的域名,‘*’表示任意域名,‘/’表示传递给同域域名

      接受消息:window.addEventListener('message',function(event){})

                     event.data从其他窗口传递来的数据,调用postMessage的message

                     event.origin发送消息窗口的origin,即targetWindow. origin

                     event.source发送消息窗口的引用,可以使用此在两个窗口之间建立双向通信                

      详细API:https://www.w3cschool.cn/fetch_api/fetch_api-lx142x8t.html

      假设在a.html里嵌套个<iframe src="http://www.b.com/b.html"></iframe>,在这两个页面里互相通信

    // a.html
    window.onload = function() {
      // a向b发送消息
      window.frames[0].postMessage("data","http://www.b.com/b.html"); 
    // a接受b发来的消息 window.addEventListener("message", function(event) { alert(event.data); });
    }
    // b.html window.onload = function() {
    // b接受a发来的消息
    window.addEventListener("message", function(event) { alert(event.data); });
    // b向a发送消息 window.parent.postMessage("a需要的数据", "http://www.a.com/a.html");
    }
  • 相关阅读:
    bzoj 3226 [Sdoi2008]校门外的区间(线段树)
    bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树)
    cf293E Close Vertices(树分治+BIT)
    点分治练习:不虚就是要AK
    点分治练习: boatherds
    bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)
    bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)
    464 整数排序Ⅱ
    445 余弦相似度
    488 快乐数
  • 原文地址:https://www.cnblogs.com/caofeng11/p/13775247.html
Copyright © 2011-2022 走看看