如何访问<embed>标签的contentWindow属性?
解决标签同源HTML内容的contentWindow访问问题
当使用<embed>加载同源HTML内容时,直接访问contentWindow会失败,这是因为<embed>的文档模型与<iframe>不同。以下是可行的解决方法:
方法1:通过contentDocument或getSVGDocument()获取内部文档
<embed>加载HTML内容后,部分浏览器会通过contentDocument暴露内部文档,部分浏览器需要用getSVGDocument()(将HTML文档视为类SVG容器处理)。必须在内容加载完成后再尝试访问,所以要监听load事件。
父页面代码示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Embed content</title> </head> <body style="margin-bottom: 3rem;"> <h1>Embed tag testing</h1> <div style="border: 1px solid maroon;width: 803px;"> <embed id="custom-embed" src="validation.html" height="500px" width="800px"> </div> <script> const embed = document.getElementById('custom-embed'); // 等待embed内容加载完成 embed.addEventListener('load', () => { // 优先尝试contentDocument,失败则用getSVGDocument const innerDoc = embed.contentDocument || embed.getSVGDocument(); if (innerDoc) { // 访问内部文档的DOM console.log('内部页面标题:', innerDoc.title); const innerElement = innerDoc.querySelector('.some-class'); if (innerElement) { innerElement.style.color = 'red'; } // 获取内部页面的window对象 const innerWindow = innerDoc.defaultView; console.log('内部window对象:', innerWindow); } else { console.error('无法获取<embed>内部文档'); } }); </script> </body> </html>
方法2:使用postMessage进行跨上下文通信
如果直接访问内部文档有兼容性问题,postMessage是更可靠的通信方式,适用于父页面与<embed>内部页面之间的数据传递和指令调用。
父页面添加消息监听
在上述父页面的<script>中追加:
// 监听来自内部页面的消息 window.addEventListener('message', (event) => { // 验证同源,避免安全风险 if (event.origin === window.location.origin) { console.log('收到内部页面消息:', event.data); // 处理消息逻辑 } });
内部页面(validation.html)代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Validation Page</title> </head> <body> <h1>内部验证页面</h1> <script> // 监听父页面消息 window.addEventListener('message', (event) => { if (event.origin === window.location.origin) { console.log('父页面消息:', event.data); // 回复消息 event.source.postMessage('内部页面已收到指令', event.origin); } }); // 主动向父页面发送消息(可选) window.parent.postMessage('内部页面加载完成', window.location.origin); </script> </body> </html>
关键注意事项
- 必须确保
<embed>的src是同源URL,否则即使上述方法也会因跨域限制失效 - 不同浏览器对
<embed>加载HTML的支持有差异,优先测试目标浏览器的兼容性 - 避免直接依赖
getSVGDocument(),它是为SVG内容设计的,但部分浏览器对HTML内容也兼容
内容的提问来源于stack exchange,提问作者suhasa
相关产品推荐
相关产品推荐

