您完全理解3层上下文分离。
- 背景页面是一个单独的页面,因此不会与可见页面共享JS或DOM。
- 内容脚本与网页的JS上下文隔离,但共享DOM。
- 您可以使用共享DOM将代码注入页面的上下文中。它可以访问JS上下文,但不能访问Chrome API。
为了进行通信,这些层使用不同的方法:
*通过Chrome API进行 *背景 <->内容交流。
最原始的是的回调
executescript,但除了单行代码外,这对于任何其他情况都是不切实际的。
常用的方法是使用Messaging。
不常见,但可以使用
chrome.storage及其
onChanged事件进行通信。
页面 <->扩展名不能使用相同的技术。
由于注入的页面上下文脚本在技术上与页面本身的脚本没有什么区别,因此您正在寻找一种与扩展程序对话的网页方法。有两种可用的方法:
- 尽管页面对
chrome.*
API的访问非常非常有限,但它们仍可以使用消息传递来联系扩展。这是通过"externally_connectable"
方法实现的。
好处是直接与扩展程序对话,但缺点是 需要从中专门将您正在使用的域白名单加入白名单
,并且您需要跟踪扩展名ID(但是由于要注入代码,因此您可以提供带有ID的代码)。如果需要在任何域上使用它,则不合适。
- 另一个解决方案是使用DOM事件。由于DOM在内容脚本和页面脚本之间共享,因此由一个人生成的事件将对另一个人可见。
该文档演示了如何使用
window.postMessage此效果。从概念上讲,使用自定义事件更为清晰。
这种方法的缺点是 要求内容脚本充当代理 。这些脚本中必须包含以下内容:
window.addEventListener("PassToBackground", function(evt) { chrome.runtime.sendMessage(evt.detail);}, false);而后台脚本使用
chrome.runtime.onMessage侦听器对此进行处理。
我建议您编写一个单独的内容脚本,并
executescript使用
file属性而不是进行调用
pre,而不要依赖其回调。消息传递更加简洁,可以多次将数据返回到后台脚本。



