在后台上下文中用于一个脚本的消息被全部接收 [英] Messages intended for one script in the background context are received by all
问题描述
我有一个具有以下结构的WebExtension:
webextension [目录]
- background.js
- page1.html
- page1.js
- page2.html
- page2.js
background.js 监听错误。如果有的话,它会指示它的回调函数用一个包含按钮的HTML页面 page2.js 来更新标签。
HTML脚本 page2.js 首先向 background.js 发送消息, background.js 回复 page2.js 。这部分工作正常。
$ b 然后,如代码中所见, page2.html 包含一个按钮,如果点击,它将执行代码回调函数。然后,它会调用 refreshIndexPage
这个消息给 page1.html 附加的 page1.js 。
问题:当我在 page2.js 和 page1.js 在 refreshIndexPage
中,来自page2的消息被发送到 background.js 。我不想要这样的事情发生。正如我将在输出中显示,我得到:在background.js:received:undefined
问题: / p>
- 如何将 page2.js 发送到 page1.js 使 background.js 也听从 page2.js 的消息会感到困惑,并收到不适合它的消息?如何将这条信息从 page2.js 指定为 page1.js ?
以下是从 page2.js 添加到 page1.js 的消息后的输出。
控制台输出
里面refreshIndexPage
在background.js中:received: undefined
内部handleRefreshResponse
- page1.html :
< html>
< head>
< meta charset =UTF-8>
< / head>
< body>
< h1> Pag1.html< / h1>
< input type =buttonid =page1-buttonvalue =click>< / input>
< script src =page1.js>< / script>
< / body>
< / html>
- page1.js :
$ b
function displayAll(){
console.log(inside display all);
} // end displayAll
//应该监听来自pag2.js的消息
browser.runtime.onMessage.addListener(handleRefreshMessage);
函数handleRefreshMessage(request,sender,sendResponse){
console.log(In page1.js:message received+ request.refreshRequest);
sendResponse(从page1.js到page2.js的响应);
- background .js :
$ b
console.log 内部背景);
//为工具栏图标添加一个侦听器。如果点击,打开page1.html
browser.browserAction.onClicked.addListener((tab)=> {
//禁用活动标签
var creating = browser.tabs.create({ (url):page1.html});
creating.then((tab)=> {
browser.browserAction.setIcon({tabId:tab.id,path:icons / red -64.png});
}); // end created.then
}); // end addListener
var target =< all_urls>;
函数日志(responseDetails){
console.log(inside response details);
errorTab = responseDetails.tabId;
if(true){
console.log(inside if);
browser.tabs.update(responseDetails.tabId,{url:page2.html});
//这个消息等待来自page2.js的请求
browser.runtime.onMessage.addListener(handleMessage);
} // end if
} // end log
函数handleMessage(request,sender,sendResponse){
console.log(in background.js:收到:+ 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 =buttonid =page2-buttonvalue =click>< / input>
< script src =page2.js>< / script>
< / body>
< / html>
- page2.js :
$ b
/ *自调用函数conatins sendMessage后台脚本* /
(函数notifyBackgroundPage(){
var sending = browser.runtime.sendMessage({
scriptRequest:from pag2.js. request for data
}) ;
sending.then(handleResponse);
})();
函数handleResponse(消息){
console.log(`在page2.js:来自后台的数据是:$ {message.errorTab}`);
} // handleResponse
函数myFunction(){
refreshIndexPage(); //结束.then
} //结束myFunction
// refreshIndexPage只有当按钮被点击时才会发送消息给page1.js。
函数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
$ b $ var page2Button = document.getElementById(page2-button);
page2Button.addEventListener('click',myFunction);
runtime.sendMessage()
在后台上下文中的所有脚本中都有收到 runtime.onMessage
监听器已注册,但是发送消息的脚本除外。 1 您无法限制这些信息的收件人。
因此,您必须创建一些方法来确定邮件是否适用于接收的每个脚本它。这可以通过各种方式来完成,但是它们都是基于以下任一方式: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/onMessage#Parameters =nofollow noreferrer> message
和/或
sender
这两个都作为参数提供给 runtime.onMessage()
监听器。使用 message
要使用 就个人而言,我通常会以不同的原因发送消息。对于每个扩展,我通常会选择总是发送一个具有特定格式的对象。这种格式对于每个扩展名可能都不相同,但是通常看起来像这样: 如果扩展名有多个可能的收件人,那么A)只有一个收件人会理解如何处理 当每个脚本收到 请记住,上面的结构正是我碰巧使用的。您可以定义任何你想要的结构,也满足你的需求。 如果一个脚本从不 对从特定发件人收到的邮件采取行动,或者只对 那么该脚本可以检查 基于对<$ c $仅仅基于 1。版本中 Firefox中的错误在51之前的结果是在发送它们的脚本中接收到消息。如果您希望在该版本中使用您的扩展程序或更早版本,您必须考虑到这种可能性(即忽略它们),因为某些情况会导致Firefox被锁定(例如,如果您始终发送新消息当你收到一条消息)。 I have a WebExtension with the following structure: The background.js listens for errors. If any, it instructs its callback function to update the tab with an HTML page, page2.js that contains a button. The HTML script page2.js starts by sending a message to the background.js and background.js replies to page2.js. This part works fine. Then, as you see in the code, page2.html contains a button if clicked, it will execute code in the callback function. Then, it will call The Problem: When I added the messaging APIs between page2.js and page1.js in the Questions: Here is the output after adding messages from page2.js to page1.js.
Console output
Messages sent by Thus, you have to create some methodology to determine if the message is intended for each script which receives it. This can be done in a wide variety of ways, but all of them are based on either: Both of these are provided as arguments to the To use the Personally, I'm usually sending messages for different reasons. For each extension, I'll usually choose to always send an Object with a particular format. That format may be different for each extension, but it usually looks something like: If the extension has multiple possible recipients, then either A) only one recipient would understand how to handle a When each script received the Keep in mind that the structure above is just what I happen to use. You can define whatever structure you desire which also fulfills your needs. If a script is never to act on messages received from a specific sender(s), or if it is to only act on messages from specific senders, then that script can check the Basing a choice to act on a 1. A bug in Firefox in versions prior to 51 results in messages being received in the script which sent them. If you expect your extension to be used in that version or earlier you must account for that possibility (i.e. ignore them), as some situations can result in locking up Firefox (e.g. if you always send a new message when you receive a message). 这篇关于在后台上下文中用于一个脚本的消息被全部接收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!消息
,您必须选择 em>在消息
上施加一些结构。 消息
可以是您选择发送的任何JSON数据。强加一些结构可以让你更容易地使用消息更复杂,更可靠地在你的脚本之间传递信息。没有什么是预定义的。你可以使用任何你想要的。然而,在你的选择中保持一致通常会使编程变得更容易,而且几乎总能使代码更易于维护。
$ b var message = {
类型:'requestFoo',
// subType:'如果类型需要进一步拆分,使用
data:dataNeededForRequest
//你可以添加任何其他属性你想在这里。
};
requestFoo
类型
消息,所有其他消息都会忽略这样的消息 types
,或者如果有多个后台上下文脚本可以处理 requestFoo
类型,那么我会添加一个收件人
或目标
属性。因此,消息
看起来像:
var message = {
type:'requestFoo',
// subType:'如果需要进一步拆分类型,使用
recipient:'page2.js',
data:dataNeededForRequest
//你可以在这里添加你想要的任何其他属性。
};
消息
时,请检查收件人
是否与接收到该邮件的脚本相匹配,以及代码是否理解如何处理类型
message
。
使用
发件人
发件人
runtime.MessageSender
查看参数是否与来自发件人的参数匹配消息
。如果你使用这种方法,你通常会检查 sender.url
。
发送者
的消息明显比基于消息的内容有限
。但是,除了在消息
中提供的信息之外,它还是非常有用的。它还提供了一种方法来知道邮件的发件人不能被欺骗。另外,这意味着你不需要传递关于哪个范围是消息发送者的信息,除非你在范围内有多个可能的发送者(即在URL /页面中)。 / p>
webextension [directory]
- background.js
- page1.html
- page1.js
- page2.html
- page2.js
refreshIndexPage
which should send a message to page1.js which is attached to page1.html.refreshIndexPage
, the message from page2 gets sent to the background.js. I do not want this to happen. As I will show in the output, I get: In background.js: received: undefined
inside refreshIndexPage
In background.js: received: undefined
inside handleRefreshResponse
<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>
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");
}
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"]
});
<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>
/*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
listener registered, except the script from which the message was sent.1 There is no way for you to restrict the recipients of such messages.runtime.onMessage()
listener.Using
message
message
you have to choose to impose some structure on the message
. The message
can be any JSON-ifiable data you choose to send. Imposing some structure allows you to more easily use messages more complex and more reliably communicate information between your scripts. There is nothing that is predefined. You can use whatever you desire. However, being consistent in your choices usually makes it easier to program and almost always makes code easier to maintain.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.
};
requestFoo
type
message, and all others would ignore such message
types
, or if there were multiple background context scripts which could handle requestFoo
types, then I would add a recipient
or destination
property. Thus, the message
would look like: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
they would check both that the recipient
matched the script which had received the message and that the code understood how to handle the type
of message
.Using
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
.message
based solely on the sender
is significantly more limited than being based on the contents of the message
. However, it can be quite useful when used in addition to information provided in the message
. It also provides a way to know the sender of the message which can not be spoofed. In addition, it means that you don't need to communicate information as to which scope was the sender of the message, unless, of course, you have more than one possible sender in the scope (i.e. in the URL/page).