为什么js无法通过contentDocument获取到iframe内容

最近在开发一个附件预览的页面,考虑到附件的安全性由后端对内容进行了加密,前端负责在页面引入iframe标签来加载数据,在这个过程中需要实时获取到iframe标签的渲染状态来判断什么时候loading结束:

这里我通过标签的方式来获取到iframe,再通过判断内部body是否有长度来确认loading状态,但是在页面中iframe加载到内容的情况下,无论怎么获取,js拿到的iframe内部都是空的

var iframe = document.getElementsByTagName('iframe')]
var loading = true
 
// 监听iframe加载完成
iframe.onload = function() {
    // 获取iframe的document对象
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
 
    // 获取iframe下的body元素
    var iframeBody = iframeDoc.body;
    loading = iframeBody.children?.length < 1
};

观察发现iframe的地址和项目的地址没有满足同源策略

同源策略限制:如果 iframe 加载的内容与主页面不在同一源(即协议、域名和端口相同),那么由于浏览器的同源策略,您将无法访问 iframe 的 contentDocument。在这种情况下,即使 iframe 已经加载完成,您也无法读取其内容。

而对于跨域 iframe,最可靠的方法是让 iframe 的内容主动通知主页面它已经渲染完成。这通常通过 postMessage 方法实现。如果您没有控制权限来修改 iframe 的内容,那么您将无法判断其渲染状态,因为浏览器的同源策略会阻止这种访问。

使用 postMessage 和 message 事件
如果跨域 iframe 的内容允许,您可以使用 window.postMessage 方法来在 iframe 和主页面之间安全地传递消息。iframe 可以在其内容加载和渲染完成后向主页面发送一个消息,主页面可以通过监听 message 事件来接收这个消息。

// 在主页面中监听来自iframe的消息  
window.addEventListener('message', function(event) {  
    if (event.origin !== '期望的iframe源的URL') return; // 安全检查  
    if (event.data === 'iframeRendered') {  
        console.log('iframe已经渲染完成');  
    }  
}, false);

在 iframe 的内容中,当渲染完成时,您可以发送消息:

// 在iframe的内容中发送消息给主页面  
window.parent.postMessage('iframeRendered', '*'); // 注意:'*' 表示接收方可以是任何源,出于安全考虑,应该替换为具体的源URL

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值