在Firefox的附加组件中,我试图将后台脚本中的代码注入选项卡,然后将消息传递给它。不幸的是,内容脚本似乎只在消息发送后才添加监听器,从而导致错误。我错过了什么?这是我的示例代码:
的manifest.json:
{
"description": "Test background to content message passing",
"manifest_version": 2,
"name": "Background content message passing",
"version": "0.1.0",
"default_locale": "en",
"applications": {
"gecko": {
"id": "bcm@example.com",
"strict_min_version": "51.0"
}
},
"permissions": [
"contextMenus",
"<all_urls>"
],
"background": {
"scripts": ["background.js"]
}
}
background.js:
"use strict";
const {contextMenus, i18n, runtime, tabs} = browser;
contextMenus.onClicked.addListener(function(info, tab) {
if (info.menuItemId == "bgd-cnt-msg") {
tabs.executeScript(tab.id, {
file: "/content.js",
})
.then(runtime.sendMessage({"result": 42}))
.then(console.log("Debug: runtime message sent"))
.catch(console.error.bind(console));
}
});
contextMenus.create({
id: "bgd-cnt-msg",
title: "Test message passing",
contexts: ["all"],
documentUrlPatterns: ["<all_urls>"]
});
content.js
"use strict";
console.log("Debug: executing content script");
browser.runtime.onMessage.addListener(function (message) {
console.log("Debug: received message %O", message);
});
console.log("Debug: added listener");
选择上下文菜单条目的结果是
Debug: runtime message sent background.js:11:15
Debug: executing content script content.js:3
Debug: added listener content.js:9
Error: Could not establish connection. Receiving end does not exist. undefined
即,在发送到选项卡的消息之后执行上下文脚本。如何在发送消息之前添加监听器?
根据@Thắng的建议,我将代码更改为使用tabs.sendMessage
而不是runtime.sendMessage
:
contextMenus.onClicked.addListener(function(info, tab) {
if (info.menuItemId == "bgd-cnt-msg") {
tabs.executeScript(tab.id, {
file: "/content.js",
})
.then(tabs.sendMessage(tab.id, {"result": 42}))
.then(console.log("Debug: runtime message sent"))
.catch(console.error.bind(console));
}
});
现在提前报告错误:
Debug: runtime message sent background.js:11:15
Error: Could not establish connection. Receiving end does not exist. undefined
Debug: executing content script content.js:3
Debug: added listener content.js:9
感谢@Thắng,他提供了一个可行的解决方案,我修改了我的代码,不仅使用了tabs.sendMessage
,还传递了回调函数:
contextMenus.onClicked.addListener(function(info, tab) {
if (info.menuItemId == "bgd-cnt-msg") {
tabs.executeScript(tab.id, {
file: "/content.js",
})
.then(function () { tabs.sendMessage(tab.id, {"result": 42}) })
.then(function () { console.log("Debug: runtime message sent") })
.catch(console.error.bind(console));
}
});
在content.js
browser.runtime.onMessage.addListener(function (message) {
console.log("Debug: result is " + message.result);
});
我现在得到了
Debug: executing content script content.js:3
Debug: added listener content.js:9
Debug: runtime message sent background.js:11:15
Debug: result is 42 content.js:6
答案 0 :(得分:1)
在后台脚本中,您需要让它知道它应该将消息发送到哪个标签,因此请不要使用runtime.sendMessage
。
var sending = chrome.tabs.sendMessage(
tabId, // integer
message, // any
options // optional object
)
在此处查看更多内容(适用于webExtensions但与Chrome兼容):https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/sendMessage
您的全功能扩展程序(您可能需要将所有browser.*
更改为chrome.*
):
https://drive.google.com/file/d/1KGf8tCM1grhhiC9XcHOjsrbBsIZGff3e/view?usp=sharing