关于iframe跨域实践(转载)

通过修改document.domain来跨子域

子域中无法获取父域的数据的时候就可以利用document.domain都设置成相同的域名就可以完成。但是要注意的是,document.domain的设置是有限制的,我们把document.domain设置成自身或者更高一级的父域,且主域必须相同。例如:a.b.example.com中某个文档的document.domaiin可以设成a.b.example.comb.example.com、example.com中的任意一个,但是不可以设成c.a.b.example.com,因为这是当前作用于的子域,也不能设成baidu.com,因为主域已经不相同了。

这种方式用来获取端口不同的跨域处理起来是很方便的:

复制代码
//父域的运行环境是http://localhost:8087/
//同样在部署在同一台服务器上的不同端口的应用也是适用的

<iframe src="http://localhost:8086/" id="iframepage" width="100%" height="100%" frameborder="0" scrolling="yes" onLoad="getData"></iframe>

<script>
    window.parentDate = {
        "name": "hello world!",
        "age": 18
    }
    /**
     * 使用document.domain解决iframe父子模块跨域的问题
     */
    let parentDomain = window.location.hostname;
    console.log("domain",parentDomain); //localhost
    document.domain = parentDomain;
</script>
复制代码
复制代码
//子域的运行环境是http://localhost:8086/

<script>
    /**
     * 使用document.domain解决iframe父子模块跨域的问题
     */
    console.log(document.domain); //localhost
    let childDomain = document.domain;
    document.domain = childDomain;
    let parentDate = top.parentDate;
    console.log("从父域获取到的数据",parentDate);   
    // 此处打印数据为
    // {
    //     "name": "hello world!",
    //     "age": 18
    // }
</script>
复制代码

到这里就能够把主域的数据传递给子域了。同样也可以把子域的数据传递子域:

复制代码
//子域的获取到top之后给top上添加属性

<script>
    let childDomain = document.domain;
    document.domain = childDomain;

    top.childData = {   //获取到top之后给top添加属性
        "name": "你好世界!",
        "age": 26
    }
</script>
复制代码
复制代码
//父域在iframe加载完成之后就可以获取到子域添加的属性

<iframe src="http://localhost:8086/" id="iframepage" width="100%" height="100%" frameborder="0" scrolling="yes" onLoad="getData"></iframe>

<script>
    getData(){
        console.log("子域传递给父域的数据",top.childData);
        // 此处打印数据
        // {
        //      "name": "你好世界!",
        //      "age": 26
        // }
    }
</script>
复制代码

这样就可以完成父子组件之间的通讯了。

不过如果你想在http://www.example.com/a.html页面中通过ajax直接请求http://example.com/b.html页面,即使你设置了相同的document.domain也还是不行的,所以修改document.domain的方法只适用于不同子域的框架间的交互。

使用HTML5中新引入的window.postMessage方法来跨域传递数据

window.postMessage(message, targetOrgin)方法是html5新引进的特性,可以使用它来想其他的window对象发送消息,无论这个window对象是属于同源或者不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

调用postMessage方法的window对象是指要接受消息的哪一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrgin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符*。

需要接收消息的window对象,可是通过监听自身的message时间来获取传过来的消息,消息内容存储在该事件对象的data属性中。

上面所有的向其他window对象发送消息,其中就是指一个页面有几个框架的那种情况,因为每一个框架都有一个window对象。在讨论第二种方法的时候,我们说过,不同域的框架间是可以获取到对象的window对象的,而且也可以使用window.postMessage这个方法。

复制代码
//父域的运行环境是http://localhost:8087/

<iframe src="http://127.0.0.1:8086/" id="iframepage" width="100%" height="100%" frameborder="0" scrolling="yes" onLoad="getData"></iframe>

<script>
    getData(){
        let iframe = document.getElementById('iframepage');
        let win = iframe.contentWindow;
        win.postMessage(JSON.stringify(parentDate),"*");
    }
</script>
复制代码
复制代码
//子域的运行环境是http://127.0.0.1:8086/

    /**
     * 使用postMessage解决iframe父子模块跨域的问题
     */
    window.onmessage = function(e){
        e = e || event;
        console.log("从父域获取到的数据",JSON.parse(e.data));
        // 此处打印的数据为
        // {
        //     "name": "hello world!",
        //     "age": 18
        // }
    }
复制代码

这样在任何一个域内都可以获取到从父域传递的数据。通过postMessage来跨域传递数据还是比较直观和方便的,但是缺点是IE6、IE7不支持,至于能不能用可以在 Can I use上进行验证。目前看到的是IE11是部分支持,不过刚才的方法在IE11上验证是能够正常执行的。

转载于:https://www.cnblogs.com/xiayizhan/p/8359072.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值