用于后台上下文中一个脚本的消息被所有脚本接收
Messages intended for one script in the background context are received by all
我有一个具有以下结构的 WebExtension:
webextension [directory]
- background.js
- page1.html
- page1.js
- page2.html
- page2.js
background.js 侦听错误。如果有的话,它会指示其回调函数使用 HTML 页面更新选项卡,page2.js 包含一个按钮。
HTML 脚本 page2.js 首先向 background.js 发送一条消息,然后background.js 回复 page2.js。这部分工作正常。
然后,正如您在代码中看到的那样,page2.html 包含一个按钮,如果单击,它将执行回调函数中的代码。然后,它将调用 refreshIndexPage
,它应该发送一条消息到附加到 page1.html 的 page1.js .
问题:当我在 page2.js 和 [=119= 之间添加消息传递 API 时] 在 refreshIndexPage
中,来自 page2 的消息被发送到 background.js。我不希望这种情况发生。正如我将在输出中显示的那样,我得到:In background.js: received: undefined
问题:
- 如何从 page2.js 发送消息到 page1.js 而无需 background.js 也在侦听来自 page2.js 的消息时会感到困惑并收到不适合它的消息吗?如何指定这条消息是从page2.js到page1.js?
这是将消息从 page2.js 添加到 page1.js 后的输出。
控制台输出
inside refreshIndexPage
In background.js: received: undefined
inside handleRefreshResponse
- page1.html:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>Pag1.html</h1>
<input type="button" id="page1-button" value="click"></input>
<script src="page1.js"></script>
</body>
</html>
- page1.js:
function displayAll() {
console.log("inside display all");
} //end displayAll
//should listen to messages from pag2.js
browser.runtime.onMessage.addListener(handleRefreshMessage);
function handleRefreshMessage(request, sender, sendResponse) {
console.log("In page1.js: message received" + request.refreshRequest);
sendResponse("response from page1.js to page2.js");
}
- background.js:
console.log("inside background");
//add a listener for the toolbar icon. If clicked, open page1.html
browser.browserAction.onClicked.addListener((tab) => {
// disable the active tab
var creating = browser.tabs.create({"url": "page1.html"});
creating.then((tab) => {
browser.browserAction.setIcon({tabId: tab.id, path: "icons/red-64.png"});
});//end creating.then
});//end addListener
var target = "<all_urls>";
function log(responseDetails) {
console.log("inside response details");
errorTab = responseDetails.tabId;
if(true) {
console.log("inside if");
browser.tabs.update(responseDetails.tabId,{url: "page2.html"});
//this message to wait request from page2.js
browser.runtime.onMessage.addListener(handleMessage);
} //end if
}//end log
function handleMessage(request, sender, sendResponse) {
console.log("In background.js: received: " + request.scriptRequest);
sendResponse({errorTab: errorTab});
}
var errorListening = browser.webRequest.onErrorOccurred.addListener(log, {
urls: [target],
types: ["main_frame"]
});
- page2.html:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>Pag2.html</h1>
<input type="button" id="page2-button" value="click"></input>
<script src="page2.js"></script>
</body>
</html>
- page2.js:
/*self-calling function conatins sendMessage to background script*/
(function notifyBackgroundPage() {
var sending = browser.runtime.sendMessage({
scriptRequest: "From pag2.js. request for data"
});
sending.then(handleResponse);
})();
function handleResponse(message) {
console.log(`In page2.js: data from background is: ${message.errorTab}`);
} //handleResponse
function myFunction() {
refreshIndexPage();//end .then
}//end myFunction
//refreshIndexPage should send message to page1.js only when the button is clicked.
function refreshIndexPage() {
console.log("inside refreshIndexPage");
var sending = browser.runtime.sendMessage({
refreshRequest: "From page2.js"
});
sending.then(handleRefreshResponse);
}//end refreshIndex
function handleRefreshResponse() {
console.log("inside handleRefreshResponse");
}//end handleRefreshResponse
var page2Button = document.getElementById("page2-button");
page2Button.addEventListener('click', myFunction);
已注册 runtime.sendMessage()
are received in all scripts in the background context which have a runtime.onMessage
侦听器发送的消息,发送消息的脚本除外。1 您无法限制此类消息的收件人.
因此,您必须创建一些方法来确定消息是否针对接收它的每个脚本。这可以通过多种方式完成,但所有方式都基于以下任一方式:
这两个都作为参数提供给 runtime.onMessage()
侦听器。
使用message
要使用 message
,您必须 选择 以在 message
上强加一些结构。 message
可以是您选择发送的任何 JSON-ifiable 数据。强加一些结构可以让您更轻松地使用更复杂的消息,并更可靠地在脚本之间传递信息。没有什么是预定义的。你可以使用任何你想要的。但是,在您的选择中保持一致通常会使编程更容易,并且几乎总是使代码更易于维护。
就个人而言,我通常会出于不同的原因发送消息。对于每个分机,我通常会选择始终 发送具有特定格式的Object。每个扩展名的格式可能不同,但通常类似于:
var message = {
type: 'requestFoo',
//subType: 'Used if the type needs to be further split',
data: dataNeededForRequest
//You can add whatever other properties you want here.
};
如果扩展有多个可能的收件人,那么 A) 只有一个收件人会理解如何处理 requestFoo
type
消息,而所有其他人都会忽略这样的 message
types
,或者如果有多个后台上下文脚本可以处理 requestFoo
类型,那么我会添加一个 recipient
或 destination
属性。因此,message
看起来像:
var message = {
type: 'requestFoo',
//subType: 'Used if the type needs to be further split',
recipient: 'page2.js',
data: dataNeededForRequest
//You can add whatever other properties you want here.
};
当每个脚本收到 message
时,他们将检查 recipient
是否与收到消息的脚本匹配,以及代码是否理解如何处理 type
message
.
请记住,上面的结构正是我碰巧使用的。您可以定义任何您想要的结构,也能满足您的需求。
使用sender
如果脚本从不对从特定发件人收到的邮件执行操作,或者如果脚本仅执行在来自特定发件人的邮件上,然后该脚本可以检查 sender
runtime.MessageSender
Object to see if the parameters match ones from a sender for which it is to act on the message
. If you use this methodology, you will most commonly be checking the sender.url
.
仅根据 sender
对 message
采取行动的选择比基于 message
的内容要受限得多。但是,除了 message
中提供的信息外,它还非常有用。它还提供了一种方法来了解不能被欺骗的消息的发件人。此外,这意味着您不需要传达关于哪个范围是消息发件人的信息,当然,除非您在范围内有多个可能的发件人(即在 URL/page 中) .
1. 51 之前的版本中的 bug in Firefox 会导致在发送消息的脚本中接收到消息。如果您希望您的扩展在该版本或更早版本中使用,您 必须 考虑到这种可能性(即忽略它们),因为某些情况可能会导致 Firefox 锁定(例如,如果您总是发送收到消息时会收到一条新消息)。
我有一个具有以下结构的 WebExtension:
webextension [directory]
- background.js
- page1.html
- page1.js
- page2.html
- page2.js
background.js 侦听错误。如果有的话,它会指示其回调函数使用 HTML 页面更新选项卡,page2.js 包含一个按钮。
HTML 脚本 page2.js 首先向 background.js 发送一条消息,然后background.js 回复 page2.js。这部分工作正常。
然后,正如您在代码中看到的那样,page2.html 包含一个按钮,如果单击,它将执行回调函数中的代码。然后,它将调用 refreshIndexPage
,它应该发送一条消息到附加到 page1.html 的 page1.js .
问题:当我在 page2.js 和 [=119= 之间添加消息传递 API 时] 在 refreshIndexPage
中,来自 page2 的消息被发送到 background.js。我不希望这种情况发生。正如我将在输出中显示的那样,我得到:In background.js: received: undefined
问题:
- 如何从 page2.js 发送消息到 page1.js 而无需 background.js 也在侦听来自 page2.js 的消息时会感到困惑并收到不适合它的消息吗?如何指定这条消息是从page2.js到page1.js?
这是将消息从 page2.js 添加到 page1.js 后的输出。 控制台输出
inside refreshIndexPage
In background.js: received: undefined
inside handleRefreshResponse
- page1.html:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>Pag1.html</h1>
<input type="button" id="page1-button" value="click"></input>
<script src="page1.js"></script>
</body>
</html>
- page1.js:
function displayAll() {
console.log("inside display all");
} //end displayAll
//should listen to messages from pag2.js
browser.runtime.onMessage.addListener(handleRefreshMessage);
function handleRefreshMessage(request, sender, sendResponse) {
console.log("In page1.js: message received" + request.refreshRequest);
sendResponse("response from page1.js to page2.js");
}
- background.js:
console.log("inside background");
//add a listener for the toolbar icon. If clicked, open page1.html
browser.browserAction.onClicked.addListener((tab) => {
// disable the active tab
var creating = browser.tabs.create({"url": "page1.html"});
creating.then((tab) => {
browser.browserAction.setIcon({tabId: tab.id, path: "icons/red-64.png"});
});//end creating.then
});//end addListener
var target = "<all_urls>";
function log(responseDetails) {
console.log("inside response details");
errorTab = responseDetails.tabId;
if(true) {
console.log("inside if");
browser.tabs.update(responseDetails.tabId,{url: "page2.html"});
//this message to wait request from page2.js
browser.runtime.onMessage.addListener(handleMessage);
} //end if
}//end log
function handleMessage(request, sender, sendResponse) {
console.log("In background.js: received: " + request.scriptRequest);
sendResponse({errorTab: errorTab});
}
var errorListening = browser.webRequest.onErrorOccurred.addListener(log, {
urls: [target],
types: ["main_frame"]
});
- page2.html:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>Pag2.html</h1>
<input type="button" id="page2-button" value="click"></input>
<script src="page2.js"></script>
</body>
</html>
- page2.js:
/*self-calling function conatins sendMessage to background script*/
(function notifyBackgroundPage() {
var sending = browser.runtime.sendMessage({
scriptRequest: "From pag2.js. request for data"
});
sending.then(handleResponse);
})();
function handleResponse(message) {
console.log(`In page2.js: data from background is: ${message.errorTab}`);
} //handleResponse
function myFunction() {
refreshIndexPage();//end .then
}//end myFunction
//refreshIndexPage should send message to page1.js only when the button is clicked.
function refreshIndexPage() {
console.log("inside refreshIndexPage");
var sending = browser.runtime.sendMessage({
refreshRequest: "From page2.js"
});
sending.then(handleRefreshResponse);
}//end refreshIndex
function handleRefreshResponse() {
console.log("inside handleRefreshResponse");
}//end handleRefreshResponse
var page2Button = document.getElementById("page2-button");
page2Button.addEventListener('click', myFunction);
已注册 runtime.sendMessage()
are received in all scripts in the background context which have a runtime.onMessage
侦听器发送的消息,发送消息的脚本除外。1 您无法限制此类消息的收件人.
因此,您必须创建一些方法来确定消息是否针对接收它的每个脚本。这可以通过多种方式完成,但所有方式都基于以下任一方式:
这两个都作为参数提供给 runtime.onMessage()
侦听器。
使用message
要使用 message
,您必须 选择 以在 message
上强加一些结构。 message
可以是您选择发送的任何 JSON-ifiable 数据。强加一些结构可以让您更轻松地使用更复杂的消息,并更可靠地在脚本之间传递信息。没有什么是预定义的。你可以使用任何你想要的。但是,在您的选择中保持一致通常会使编程更容易,并且几乎总是使代码更易于维护。
就个人而言,我通常会出于不同的原因发送消息。对于每个分机,我通常会选择始终 发送具有特定格式的Object。每个扩展名的格式可能不同,但通常类似于:
var message = {
type: 'requestFoo',
//subType: 'Used if the type needs to be further split',
data: dataNeededForRequest
//You can add whatever other properties you want here.
};
如果扩展有多个可能的收件人,那么 A) 只有一个收件人会理解如何处理 requestFoo
type
消息,而所有其他人都会忽略这样的 message
types
,或者如果有多个后台上下文脚本可以处理 requestFoo
类型,那么我会添加一个 recipient
或 destination
属性。因此,message
看起来像:
var message = {
type: 'requestFoo',
//subType: 'Used if the type needs to be further split',
recipient: 'page2.js',
data: dataNeededForRequest
//You can add whatever other properties you want here.
};
当每个脚本收到 message
时,他们将检查 recipient
是否与收到消息的脚本匹配,以及代码是否理解如何处理 type
message
.
请记住,上面的结构正是我碰巧使用的。您可以定义任何您想要的结构,也能满足您的需求。
使用sender
如果脚本从不对从特定发件人收到的邮件执行操作,或者如果脚本仅执行在来自特定发件人的邮件上,然后该脚本可以检查 sender
runtime.MessageSender
Object to see if the parameters match ones from a sender for which it is to act on the message
. If you use this methodology, you will most commonly be checking the sender.url
.
仅根据 sender
对 message
采取行动的选择比基于 message
的内容要受限得多。但是,除了 message
中提供的信息外,它还非常有用。它还提供了一种方法来了解不能被欺骗的消息的发件人。此外,这意味着您不需要传达关于哪个范围是消息发件人的信息,当然,除非您在范围内有多个可能的发件人(即在 URL/page 中) .
1. 51 之前的版本中的 bug in Firefox 会导致在发送消息的脚本中接收到消息。如果您希望您的扩展在该版本或更早版本中使用,您 必须 考虑到这种可能性(即忽略它们),因为某些情况可能会导致 Firefox 锁定(例如,如果您总是发送收到消息时会收到一条新消息)。