// To access the `window` of a background page, use
var bgWindowObject = chrome.extension.getBackgroundPage();
// To access the `window` of an event or background page, use:
chrome.runtime.getBackgroundPage(function(bgWindowObject) {
// Do something with `bgWindow` if you want
});
// To access the `window` of the badge's popup page (only if it's open!!!), use
var popupWindowObject = chrome.extension.getViews({type:'popup'})[0];
// To access the `window` of the options page (called /options.html), use
var allWindowObjects = chrome.extension.getViews({type:'tab'});
var popupWindowObjects = allWindowObjects.filter(function(windowObject) {
return windowObject.location.pathname == '/options.html';
});
// Example: Get the `window` object of the first options page:
var popupWindowObject = popupWindowObjects[0];
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message === 'message') sendResponse('the response');
});
chrome.runtime.sendMessage('message', function(response) {
console('sendResponse was called with: ' + response);
});
前面的例子显示了明显的行为。当你想异步发送一个响应时,事情就变得棘手了,例如,如果你想执行一个 AJAX 请求来获取一些数据。当onMessage函数返回时没有调用sendResponse,Chrome将立即调用sendResponse。由于sendResponse只能被调用一次,你将收到以下错误: 无法发送响应:如果你想在chrome.runtime.onMessage监听器返回后发送一个响应(消息是由扩展名 EXTENSION ID HERE 发送的),那么它必须返回true 按照错误提示执行操作,在onMessage事件侦听器中添加return true;:
我已经有一段时间没有处理chrome的扩展了。我记得在我弄明白它是如何工作之前,我经历了相当大的斗争。为了让你的扩展与浏览器通信,你可以很容易地使用你的javascript/background文件。要与网页进行通信,您需要使用chrome.tabs.executeScript,但这确实很棘手,可能是一个真正的麻烦。我建议你选择google's tour on extensions,并给予他们的API一个真正的好忽略,一切都在那里!我祝你好运,我希望这个答案对你有帮助!:P
3条答案
按热度按时间ca1c2owp1#
∮三种不同的背景∮
作为Chrome扩展程序开发人员,您可以区分三种不同的环境。
*扩展代码,在Chrome扩展进程中运行
*非扩展代码在选项卡的进程中运行(injected by content scripts)。
请注意,非扩展页面中的
<iframe src="chrome-extension://EXTENSIONID/page.htm">
通常被视为第二种情况(内容脚本),因为框架是在一个非特权的标签进程中加载的。由于out-of-process iframes是为Chrome 56中的扩展启动的,因此这些页面由扩展进程处理,因此它们可能使用相同的扩展API全集。访问扩展进程中的
window
对象因为所有的扩展代码都在同一个进程中运行,所以它们可以访问彼此的全局
window
对象。这个特性并不广为人知,但是允许在同一个扩展进程中直接操作JavaScript和DOM对象。通常最好不要使用这个方法,而是使用message passing API。为了使本节简短,我特意将代码示例限制为访问其他全局
window
对象的演示,您可以使用这些方法定义全局方法、设置全局变量、调用全局函数等。...假设页面是打开的。某人thought弹出窗口的
window
总是可用的。这是不正确的,当弹出窗口关闭时,全局对象被释放!通过message passing进行通信
消息通道始终有两个端点:发送者和接收者。
要成为接收者,使用
chrome.runtime.onMessage.addListener
方法绑定一个事件监听器,这可以通过扩展代码和内容脚本来完成。要在扩展内传递消息,请使用
chrome.runtime.sendMessage
。如果要将消息发送到另一个选项卡,请调用chrome.tabs.sendMessage
。目标选项卡通过将整数(tabId
)作为其第一个参数来指定。请注意,背景页面只能将消息发送到一个选项卡。要访问所有选项卡,必须为每个选项卡调用该方法。例如:内容脚本只能调用
chrome.runtime.sendMessage
向扩展代码发送消息。如果您想从一个内容脚本向另一个内容脚本发送消息,则需要一个后台/事件页面,该页面接收消息并将其发送到所需的选项卡。请参阅此答案中的示例。sendMessage
方法接受可选函数,该函数作为onMessage
事件的第三个参数接收。前面的例子显示了明显的行为。当你想异步发送一个响应时,事情就变得棘手了,例如,如果你想执行一个 AJAX 请求来获取一些数据。当
onMessage
函数返回时没有调用sendResponse
,Chrome将立即调用sendResponse
。由于sendResponse
只能被调用一次,你将收到以下错误:无法发送响应:如果你想在chrome.runtime.onMessage监听器返回后发送一个响应(消息是由扩展名 EXTENSION ID HERE 发送的),那么它必须返回true
按照错误提示执行操作,在onMessage事件侦听器中添加
return true;
:我在本节中解释了简单的一次性消息传递的实际应用,如果你想了解更多关于长寿命消息通道或跨扩展消息传递的信息,请阅读tutorial from the official documentation。
消息传递API已经经历了几次名称更改。如果您阅读了以前的示例,请记住这一点。历史和兼容性说明可以在这里找到。
内容脚本和页面之间的通信
与页面进行通信是可能的。Apsillers给出了一个很好的答案,解释了如何在(非扩展)页面和内容脚本之间建立通信通道。请阅读他的答案:网站能否调用浏览器扩展?
apsiller的方法相对于文档中的方法的优点是使用了一个自定义事件,文档使用
window.postMessage
向页面发送消息,但这可能会导致与不期望消息事件的编码错误的页面发生冲突。2o7dmzc52#
Google文档包含了所有的信息,但是很难将所有的信息整合在一起。主要有两种类型的脚本:
1.后台脚本可以完全访问Chrome api,但无法与目标网页交互。
2.内容脚本可以相互交互,也可以与网页的DOM交互(但不能与其脚本交互,因为它是独立的),但只能有限地访问Chrome api。
无论何时加载新页面(除非您使用"matches"来限制内容脚本的运行位置),这两个脚本都会运行。
您可以通过message passing在两者之间进行通信,这在内容脚本中比在后台脚本中更容易实现,因为您需要知道后者的标签ID。
其他脚本(
browserAction.js
、pageAction.js
、optionsPage.js
)只有在对应的html页面打开时才运行(就好像你在浏览器窗口中打开网页,这才是你真正在做的事情),它们在限制和能力上与后台脚本类似。尽量避免与页面脚本交互。我所知道的最好的方法是通过共享DOM交互(实际上就是在html注解中编写javascript代码)。但是你的扩展的目标不是为此设计的,所以你必须在网页中包含你自己的脚本。使用内容脚本将脚本元素写入文档(它的
src
是chrome.extension.getURL("myscript.js")
,你需要
"web_accessible_resources": ["myscript.js"]
在你的旅客名单上。
hwazgwia3#
我已经有一段时间没有处理chrome的扩展了。我记得在我弄明白它是如何工作之前,我经历了相当大的斗争。为了让你的扩展与浏览器通信,你可以很容易地使用你的javascript/background文件。要与网页进行通信,您需要使用
chrome.tabs.executeScript
,但这确实很棘手,可能是一个真正的麻烦。我建议你选择google's tour on extensions,并给予他们的API一个真正的好忽略,一切都在那里!我祝你好运,我希望这个答案对你有帮助!:P