美文网首页
windowApi实现iframe数据跨域通信

windowApi实现iframe数据跨域通信

作者: squidbrother | 来源:发表于2019-12-17 20:33 被阅读0次
    概述

    window.postMessage()方法安全地启用Window对象之间的跨源通信
    提供了一种受控机制来规避同源策略的限制

    兼容性:


    兼容性.png
    语法格式:

    【发送数据语法】
    targetWindow.postMessage(message,targetOrigin,[ transfer ])
    参数信息:

    • targetWindow:
      iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames
    • message:
      将要发送到其他 window的数据(它将会被结构化克隆算法序列化,保证数据安全)
    • targetOrigin:
      如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。
      不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点
    • transfer:
      是一串和message 同时传递的 Transferable 对象.
      这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权

    【接收数据语法】

    window.addEventListener("message", receiveMessage, false);
    function receiveMessage(event){
      var origin = event.origin || event.originalEvent.origin; 
      if(origin !== "http://www.aaa.com:8080"){ return;}
      console.log(event.data)
    }
    

    参数信息:

    • event.data
      从其他 window 中传递过来的对象
    • origin
      调用 postMessage 时消息发送方窗口的 origin
      这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成
      【注】: 这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。
    • event.source
      对发送消息的窗口对象的引用
    实例

    情景,主页面嵌套了一个非同源的iframe,且需要进行数据交互
    主页面域名 http://www.a.com
    iframe嵌套域名 http://www.b.com

    主页面:源信息(http://localhost

    //iframe内嵌页面的(源 协议、IP地址、端口号)
    var iframeOrigin = 'http://106.x.x.4:8099';
    
    //--显示支付
    var _gameOptionsBox = $('#gameOptionsBox');
    var _payFrameBox = $('#payFrameBox');
    //iframe元素
    var _oF = $('#payFrame').get(0);
    //传递的信息
    var _mes = '传递子iframe的信息';
    $('#showPayPopBtn').bind('click',function(){
        $('#payFrame').attr('src',(iframeOrigin+'/gamebox/pay.html?goodsName=110元宝&goodsPay=280.00'));
        _gameOptionsBox.hide(); 
        _payFrameBox.show();
        
        _oF.onload = function(){
                    //iframe跨域 发送信息
            _oF.contentWindow.postMessage(_mes,iframeOrigin);
        }
    });
    
    //iframe跨域 接收信息
    window.addEventListener("message", receiveMessage, false);
    function receiveMessage(ev){
        //筛选信任接收源
        if(ev.origin == iframeOrigin){
            //console.log('正确源')
            if(ev.data){
                var _tagN = ev.data.tagN;
                var _payWay = ev.data.payWay;
                
                alert('支付方式 '+_payWay);
                $(document.getElementById(_tagN)).slideUp(300);
            }
        }else{
            console.log('发送源不可信');
            return;
        }
    }
    

    iframe页面内 源信息(http://106.x.x.4:8099

    //接收iframe postMessage跨域信息
    window.addEventListener("message", receiveMessage, false);
    function receiveMessage(event){
            //信息发起源
        var frameBoxOrigin = event.origin || event.originalEvent.origin;
        var frameBoxSource = event.source;
            
            //不是发送源直接返回
        if(frameBoxOrigin!='http://localhost'){ 
        console.log('发送源不可信');
        return;
        }
    
            //iframe内关闭按钮
        $('#closeFrameBtn').on('click',function(){
             //传递到iframe父级的信息
            var returnData = {'tagN':'payFrameBox','payWay':'微信支付'}; 
            frameBoxSource.postMessage(returnData,frameBoxOrigin);
        });
    }
    
    备注

    onmessage接收信息的时候

    1. 需要确定发送源是否是安全的,因为postMessage被调用后可能被导航到不同的位置
    2. event.origin存在兼容性问题(For Chrome, the origin property is in the event.originalEvent object.)

    相关文章

      网友评论

          本文标题:windowApi实现iframe数据跨域通信

          本文链接:https://www.haomeiwen.com/subject/zujenctx.html