iframe外部和iframe内部使用不同服务(不同源),iframe内部获取iframe外部数据; Failed to execute ‘postMessage‘ on ‘DOMWindow‘:
index.vue:138 Failed to execute 'postMessage' on 'DOMWindow'; iframe内外不同源通信;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自测无效)
/*
希望对你有帮助!
如有错误,欢迎指正,非常感谢!
*/
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)