跨域<embed>元素重定向后如何识别或发送postMessage?
我正在开发一款基于MV3的Chrome扩展,目标是把页面上所有iframe/embed/object框架转换为Shadow Root(将内容内联)。因为全选页面时,无法直接把这些框架里的内容复制粘贴到OneNote、Word等工具,必须逐个选择框架内容,非常耗时。转换后用户就能通过一次Ctrl+C批量复制所有内容。
已尝试的失败方案
postMessage
已解决iframe转换问题:通过chrome.webNavigation.getAllFrames注入每个框架及其父框架,借助postMessage传递内容,并用getAllFrames获取的frameId识别子框架完成替换。但框架无法处理:
元素(HTMLEmbedElement)没有contentWindow或contentDocument属性,无法从父框架向其发送postMessage。
window.frames
尝试用window.frames[]获取内容,它包含对应的window对象,但仅在同源场景下能通过frames[i].frameElement与元素匹配,无法判断非同源时该项所属的特定。此外,ShadowDOM中的框架不会暴露在全局window/frames中,同时存在跨域限制问题。
frame.src
对比getAllFrames获取的frame src(或embed对应的window.location.href)与父框架中元素的src属性来识别目标embed,但embed重定向后其src属性不会更新,该方法失效。
getFrameId()
runtime.getFrameId()看似能解决所有识别问题,但Chrome未实现该API,仅Firefox支持。
不理想的方案
webrequest
用webrequest API拦截重定向并保存最终URL,但需要刷新页面,不仅增加等待时间,还会导致页面上的
等折叠元素重新关闭,影响用户体验。禁用Web安全
通过Chrome启动参数禁用Web安全可解决跨域问题,但该参数存在安全风险,不能日常使用,且每次启动新Chrome实例都需要手动设置,耗时繁琐。
目前无法通过frame.src(重定向场景)、postMessage、window.frames(跨域/ShadowDOM场景)识别embed框架,寻求其他可行解决方案。
测试用例
<div><embed src="https://iperasolutions.com" height="500" width="500"></div>
后续测试更新
针对chrome.debugger方案的测试结果
chrome.debugger方案对跨域框架无效,存在公开已知bug。
针对DOM/Page类CDP方法的测试结果
DOM.getDocument、Page.getFrameTree、Page.getResourceTree、DOM.requestChildNodes这些CDP方法均不返回跨域框架,仅在禁用Web安全时有效。
Chrome v124+潜在修复(未测试)
需使用CDP自动附加功能,但该功能仅支持Chrome v124及以上版本,无法在Win7系统的Chrome v109上使用。
内容的提问来源于stack exchange,提问作者Badr Elmers
<div><embed src="https://iperasolutions.com" height="500" width="500"></div>

