• iFrame跨域解决办法


    按情境分
    1、不跨域时
    2、主域相同、子域不同时
    3、主域不同

    不跨域时
    访问iframe: contentWindow
    访问父级:parent
    访问顶级:top

     a.html 

    <html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
        <title>A</title> 
    </head> 
    <body> 
        <textarea id="message">这是高层的密码!</textarea><br/> 
        <button id="test">看看员工在说什么</button><br/><br/><br/>
        员工们:<br/> 
        <iframe src="b.htm" width="500" height="300" id="iframe"></iframe> 
        <script> document.getElementById("test").onclick = function(){ 
        alert(document.getElementById(
    "iframe").contentWindow.document.getElementById("message").value);
      }
    </script> </body> </html>

     b.html 

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>JSONP方式</title><script type="text/javascript" src="/js/jquery-1.5.1.min.js"></script> </head>
    <body> 
        <textarea id="message">这是员工的密码!</textarea><br/>
        <button id="test">看看领导在说什么</button><br/> 
        <script> document.getElementById("test").onclick = function(){ alert(parent.document.getElementById("message").value); } </script>
    </body>
    </html>



    跨域时

    1、主域相同、子域不同
    使用document.domain=主域名

    a.html (http://a.xxx.com/js/crossdomain/demo/a.htm)

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>A</title>
    </head>
    <body>
    <textarea id="message">这是高层的密码!</textarea><br/>
    <button id="test">看看员工在说什么</button><br/><br/><br/>员工们:<br/>
    <iframe src="http://b.xxx.com/js/crossdomain/demo/b.htm" width="500" height="300" id="iframe"></iframe>
    <script>
    
       document.domain = "jiaju.com";
    
       document.getElementByI d("test").onclick = function(){
            alert(document.getElementByI d("iframe").contentWindow.document.getElementByI d("message").value);
        }
    </script>
    </body>
    </html>

    b.html ((http://b.xxx.com/com/js/crossdomain/demo/b.htm ))

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>JSONP方式</title>
    <script type="text/javascript" src="/js/jquery-1.5.1.min.js"></script>
    </head>
    <body>
    <textarea id="message">这是员工的密码!</textarea><br/>
    <button id="test">看看领导在说什么</button><br/>
    <script>
        document.domain = "jiaju.com";
        document.getElementByI d("test").onclick = function(){
            alert(parent.document.getElementByI d("message").value);
        }
    </script>
    </body>
    </html>

    两个域都设置:document.domain=‘jiaju.com’

    2、主域不同
    解决办法:
    1、location.hash
    2、window.name
    location.hash
    location.hash 是什么:
    hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)
    http://www.xxx.com/js/crossdomain/proxy.html#iframeID=google&height=362&JJtype=height

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>jiaju.com iframe proxy</title>
    </head>
    <body>
    <script>
    var hash_url = window.location.hash,
          datas = hash_url.split("#")[1].split("&"),
          data = {};
    
    for(var i = 0;i<datas.length;i++){
        var t = datas[i].split("=");
        data[t[0]] = decodeURIComponent(t[1]);
    }
    document.domain = "jiaju.com";
    switch(data["JJtype"])
        {
            case "height":
                try{top.window.document.getElementByI d(data["iframeID"]).height = data["height"];}catch(e){}
                break
            case "width":
                try{top.window.document.getElementByI d(data["iframeID"]).width = data["width"];}catch(e){}
                break
            case "callback":
                try{top.window[data["fn"]].call(document,data);}catch(e){}
                break
            default:
        }
    </script>
    </body>
    </html>

    例子
    location.hash(A操作B)
    A通过location.hash方式传递参数给B,B通过定时器检测hash变化,执行对应操作。
    a.html(http://www.aaa.com/demo/cross/iframe03/a.htm)

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>A</title>
    </head>
    <body>
    <textarea id="message">这是高层的密码!</textarea><br/>
    <button id="test">看看员工在说什么</button><br/><br/><br/>员工们:<br/>
    <iframe src="http://www.bbb.com/demo/cross/iframe03/b.htm#message=111" width="500" height="300" id="iframe"></iframe>
    <script>
        var iframe = document.getElementByI d("iframe")
        document.getElementByI d("test").onclick = function(){
            var url = iframe.src,
            time = (new Date()).getTime();
            if(url.indexOf("message") != -1){
               iframe.src = url.replace(/message=w+/,"message="+time);
            }else {
                iframe.src = url+"/#message="+time;
            }
        }
    </script>
    </body>
    </html>

    b.html

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>JSONP方式</title>
    <script src="/js/crossdomain/crossdomain.js"></script>
    </head>
    <body>
    <textarea id="message">这是员工的密码!</textarea><br/>
    <button id="test">看看领导在说什么</button><br/>
    <script>
    var data = {};
    var hash_url;
    function dealHash(){
        hash_url = window.location.hash;
         var  datas = hash_url.split("#")[1].split("&");
        for(var i = 0;i<datas.length;i++){
            var t = datas[i].split("=");
            data[t[0]] = decodeURIComponent(t[1]);
        }
    }
    function change(){
        if(hash_url!=window.location.hash){
            dealHash();
            document.getElementByI d("message").value = data["message"];
        }
    }
    setInterval(change,100);
    </script>
    </body>
    </html>

    location.hash(B操作A)
    A创建和上层同域的iframe通过location.hash方式传递参数给B ,B通过top.window获取顶层window对象A
    a.html(http://www.aaa.com/demo/cross/iframe03/a.htm)

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>A</title>
    <script>
        document.domain = "jiaju.com";
        function test(obj){
           alert(obj['message']);
        }
    </script>
    </head>
    <body>
    这里是A(第一层)<br/>
    <iframe id="google" src="http://www.bbb.com/demo/crossiframe/b.html" width="1000" height="300" border=1></iframe>
    </body>
    </html>


    b.html(http://www.bbb.com/demo/crossiframe/b.html)

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>B</title>
    </head>
    <body style="
    <script src="/js/crossdomain/crossdomain.js"></script>
    这里是B(第二层)iframe<br/>
    <div id="div" style="height:200px;color:#fff;">这里高度可以变化</div>
    <button id="btn">点击改变高度</button><button id="btn2">点击调用顶层callback</button>
    <script>
    document.getElementByI d("btn").onclick = function(){
        var div = document.getElementByI d("div");
        div.style.height = (parseInt(div.style.height)+100)+"px";
        JJcrossiframe.setHeight("google");
    }
    
    document.getElementByI d("btn2").onclick = function(){
        JJcrossiframe.callback("test",{
            message:"来自跨域的iframe的问候!"
        });
    }
    </script>
    </body>
    </html>

    location.hash原理:
    1、动态改变location.hash,iframe不会重载
    2、无论跨域与否,iframe内可以获取自己的location.hash
    3、只要域名相同就能通信,即使ABC三层嵌套
    location.hash通用解决办法:
    被嵌入的跨域的iframe中引入
    <script src="/js/crossdomain/crossdomain.js"></script>

    提供以下方法:
    JJcrossiframe.setHeight(‘youiframeID’) //自动设定跨域iframe高度
    JJcrossiframe.setWidth(‘youiframeID’)  //自动设定跨域iframe宽度
    JJcrossiframe.callback(‘fn’,paramobj)  //调用顶层iframe中fn函数
    JJcrossiframe.init(paramobj , type)             //自定义向顶层传参数
    //  (type目前有:height,width,callback),
    //  新增type需在代理页面内自定义开发

    location.hash缺点
    1、传递数据量有限
    2、不太安全



    window.name
    window.name 是什么:
    name 在浏览器环境中是一个全局window对象的属性
    当在 iframe 中加载新页面时,name 的属性值依旧保持不变
    name 属性仅对相同域名的 iframe 可访问
    window.name 的优势:
    数据量更大(2M)
    更安全
    可传递多种数据格式
    window.name 的劣势:
    只适用于隐藏iframe的情形

    国内起源:
    怿飞博客: http://www.planabc.net/2008/09/01/window_name_transport/
    张克军的例子
    http://hikejun.com/demo/windowname/demo_windowname.html
    原理(1) :
    A创建iFrame B,把要传递的数据放入window.name

  • 相关阅读:
    html+css 笔记
    JS随手笔记
    JQ几个淡入淡效果
    AngularJS编译阶段应分为两个阶段
    JavaScript 原型链的理解
    js继承的6种方式
    什么是跨域?跨域解决方法
    computed (计算属性) 和 methods (方法) 的区别
    谈谈vue生命周期
    基本类型有哪几种?null 是对象吗?基本数据类型和复杂数据类型存储有什么区别?
  • 原文地址:https://www.cnblogs.com/boystar/p/6909214.html
Copyright © 2020-2023  润新知