目录

一、问题

二、解决方案

1.方式一

2.方式二

3.方式三

三、使用postMessage时可能会出现以下问题

四、总结


tiips:如嫌繁琐,直接移步总结即可!

一、问题

1.ifraeme内外不同源时应该如何 在iframe内部获取外部的数据内?浏览器一直报错跨域。

二、解决方案

1.方式一

1)document.domain 内外都设置为对方需要访问的ip或域名

2)内部使用 window.parent.xxxx:取iframe外部的属性或方法即可

    外部使用 window.contentWindow.xxx:取iframe内部的属性和方法

      // iframe外部
      document.domain="10.13.0.26"
      window.testAttribute='test'
      let iframe=document.getElementById('patientIframe')
      iframe.onload=()=>{
        console.log('iframe sessionStorage in father',iframe.contentWindow.testData,iframe.contentWindow.testFunction)
      }


      // iframe内部      
      //方式一:iframe内部和外部通信:内外都要设置 document.domain
      //注 document.domain只能是 域名或者ip(不能包含端口或其他路径)
      document.domain='10.13.0.26'
      console.log("iframe sessionStorage in son",window.parent.sessionStorage,window.parent.testAttribute)
      window.testData='testDataInner'
      window.testFunction=()=>{
        console.log("testFunction execute")
      }

3)效果

2.方式二

1)iframe url添加参数

<iframe :src="xxx?params={}“></iframe>

2)iframe内部从 route中获取 

const {proxy}=getCurrentInstance();   

proxy._routerRoot._route?.query //params={}

3)效果

3.方式三

给谁发消息window.postMessage

1)iframe外部

     //(控制台报错: Failed to execute 'postMessage' on 'DOMWindow': The target origin provided  ——onload后再发消息;iframe内部收不到数据或有时可以有时不可以拿到数据——添加延时setTimeout)

      //iframe 发消息给iframe内部

      let iframe=document.getElementById('patientIframe')

      if(iframe){

        iframe.onload=()=>{

            setTimeout(()=>{

              iframe.contentWindow.postMessage({type:'fromFather',message:sessionStorage.getItem('patManage_active_tab')},'http://10.13.0.26:8080')

            },400)

        }

      }

      //接收iframe内部传递回来的消息

      window.addEventListener('message',function(event){

        if(event.origin=='http://10.13.0.26:8080' && event.data.type==='fromSon'){

          console.log("iframe sessionStorage in father",event,event.data?.message)

        }

      })

2)iframe内部

      //监听从iframe外部发送的消息

      window.addEventListener('message',function(e){

          console.log("iframe sessionStorage son",e,e.data)

          if(e.origin=='http://10.13.0.26:4015' && e.data.type==='fromFather'){

             //事件处理

          }

        })

      //给iframe外部发消息

      window.parent.postMessage({

      type:'fromSon',

      message:'hello,message from son'

      },'http://10.13.0.26:4015')

3)效果

三、使用postMessage时可能会出现以下问题

1.控制台报错:index.vue:138 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://10.13.0.26:8080') does not match the recipient window's origin ('http://10.13.0.26:4015').

  1)原因及解决方式

        postMessage必须在iframe加载后才能调用,所以要放在 iframe.onload函数里面

2.iframe内部收不到数据或有时可以有时不可以拿到数据

     1)原因及解决方案

            iframe外部发消息时,iframe内部的addEventListener事件还没有注册

            iframe外部发送消息时,添加延时(具体时间需要根据业务需求自己测试)

四、总结

1.方式一 document.domain、方式三 postMessage可以 iframe内部和外部可以互相通信

2.方式二 src传参只能用于iframe内部获取iframe外部的数据

3.postMessage必须 放在iframe.onload里面; 接收不到货有时接收不到数据:postMessage时可以尝试使用setTimeout添加延时(nextTick自测无效)

/*

希望对你有帮助!

如有错误,欢迎指正,非常感谢!

*/

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐