我正在开发带有清单的Chrome扩展程序,该清单目前可以访问所有主机。后台脚本将内容脚本注入所有框架。加载DOM后,首页/框架中的内容脚本开始遍历DOM树。当步行者遇到iframe时,它需要向该iframe窗口关联的特定内容脚本发送消息(可能是跨源)以开始其工作,并在此消息中包括一些序列化数据。父窗口将暂停执行,并等待子窗口完成遍历,并向其发送一条消息,告知其已完成序列化数据。父母然后继续工作。我尝试了两种方法来解决此问题:
frameElement.contentWindow.postMessage
:这在大多数情况下有效,但并非总是如此。有时,与iframe窗口关联的内容脚本消息事件侦听器从不接收该消息。我无法确定原因,但我认为是在我的听众打电话之前已附加了听众event.stopImmediatePropagation()
。例如,在yahoo主页(https://www.yahoo.com)上,将消息发布到与iframe源https://s.yimg.com/rq/darla/2-9-相关联的我的内容脚本时9 / html / r-sf.html,该消息永远不会收到。这是与广告相关的iframe。也许阻止消息是有意的。发布消息时没有错误,并且我使用“ *”的targetOrigin。chrome.runtime.sendMessage
:我可以向后台页面发送消息,但无法弄清楚如何告诉后台页面将消息中继到哪个帧。父窗口内容脚本不知道与DOM遍历中遇到的子框架元素相关联的chrome扩展frameId。因此,它无法告诉后台页面如何定向消息。对于第2点,我尝试了两种在stackoverflow上发现的技术:
window.frames
数组中的位置,然后使用该索引将消息发布到后台页面。后台页面将消息发布到消息数据中具有所需索引的所有帧。仅在window.parent.frames数组中找到其窗口对象位置的iframe会与从消息中接收到的索引匹配,从而继续进行遍历。这可以正常工作,但是window.frames
在异步消息传递过程中容易受到阵列中更改的影响(如果在发送消息后删除iframe,则索引值可能不再与所需的帧匹配)。frameElement.name
在父窗口中使用而不是第1点的索引值。使用相同的消息传递技术,将名称发送给子iframe以与其window.name
值进行比较。我相信window.name
从frameElement.name
创建iframe元素时就可以得到它的价值。但是,由于我不控制框架元素的创建,因此name属性通常是一个空字符串,不能依赖于将iframe元素唯一地匹配到它们的窗口。我有办法可靠地将消息发送到与在DOM树中行走时找到的iframe元素相关联的内容脚本吗?
chrome.runtime.sendMessage
从内容脚本调用时,chrome.runtime.onMessage
侦听器的第二个参数(“发送者”)包括属性url
和frameId
。您可以(从一个扩展页面,例如背景页)将消息发送到特定的框架使用chrome.tabs.sendMessage
与给定的frameId
。
如果您想随时了解所有框架的列表(及其框架ID),请使用chrome.webNavigation.getAllFrames
。如果这样做,则可以在选项卡中构造框架树,然后将该信息发送到所有框架以进行进一步处理。
postMessage
/onMessage
frameElement.contentWindow.postMessage
:这在大多数情况下有效,但并非总是如此。有时,与iframe窗口关联的内容脚本消息事件侦听器从不接收该消息。我无法确认原因,但我认为是在我的听众打电话之前已附加了听众event.stopImmediatePropagation()
可以通过在以下位置运行脚本"run_at":"document_start"
并立即注册message
事件侦听器来对此进行反击。然后,您的处理程序将始终被首先调用,并且页面无法通过取消它event.stopImmediatePropagation()
。但是,请勿盲目地信任其他框架中的信息,并始终验证消息(例如,通过后台页面与其他框架进行通信)。
第一种方法提供了一种在框架之间交换数据的安全方法,但是没有提供将框架链接到特定DOM元素的通用方法。
第二种方法允许您定位特定的(i)frame元素,但是任何网页都可以这样做,因此该方法本身并不可靠。通过将两者结合起来,您可以获得链接到DOM元素的安全通信通道。
这是一个应用上述方法在帧A和B之间进行通信的基本示例:
A中的内容脚本:
背景页面:
crypto.getRandomValues
)。frameId
(以及可选的包含在来自A的消息中的其他信息)。A中的内容脚本:
postMessage
在框架B和通- [R 。B中的内容脚本:
注意:对于坚如磐石的应用程序,您需要考虑以下事实:在所有这些步骤中都删除了框架。如果您忽略了此过程的异步性质,则可能会使应用程序处于不一致状态。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句