- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个具有以下结构的 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.js 发送一条消息,该消息附加到 page1.html。
问题:当我在 refreshIndexPage
中的 page2.js 和 page1.js 之间添加消息 API 时>,来自 page2 的消息被发送到 background.js。我不希望这种情况发生。正如我将在输出中显示的那样,我得到: In background.js: returned: undefined
问题:
以下是将消息从 page2.js 添加到 page1.js 后的输出。控制台输出
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()
发送的消息在后台上下文中的所有脚本中都会收到 runtime.onMessage
监听器已注册,发送消息的脚本除外。1您无法限制此类消息的收件人。
因此,您必须创建一些方法来确定该消息是否适用于接收它的每个脚本。这可以通过多种方式完成,但所有方式都基于以下任一方式:
这两者都作为参数提供给 runtime.onMessage()
监听器。
消息
要使用消息
,您必须选择在消息
上强加一些结构。 消息
可以是您选择发送的任何 JSON 数据。强加一些结构可以让您更轻松地使用更复杂的消息,并更可靠地在脚本之间传递信息。没有什么是预先定义的。您可以使用任何您想要的东西。然而,保持一致的选择通常会使编程变得更容易,并且几乎总是使代码更易于维护。
就我个人而言,我通常出于不同的原因发送消息。对于每个分机,我通常会选择始终发送 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
属性。因此,消息
将如下所示:
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.
};
当每个脚本收到消息
时,它们会检查接收者
是否与接收消息的脚本匹配,以及代码是否理解如何处理
。消息
的类型
请记住,上面的结构正是我碰巧使用的。您可以定义任何您想要的结构,这也能满足您的需求。
发送者
如果脚本从不对从特定发件人收到的消息进行操作,或者如果它仅对来自特定发件人的消息进行操作,那么脚本可以检查发件人
runtime.MessageSender
对象以查看参数是否与要对其执行消息
的发送者的参数匹配。如果您使用此方法,您通常会检查 sender.url
.
仅根据发送者
来选择对消息
采取行动,比根据消息
的内容选择采取行动的局限性要大得多。然而,当除了消息
中提供的信息之外使用时,它会非常有用。它还提供了一种了解消息发送者的方法,该方法不能被欺骗。此外,这意味着您不需要传达关于哪个范围是消息发送者的信息,当然,除非您在该范围内(即在 URL/页面中)有多个可能的发送者。
1。一个bug in Firefox在 51 之前的版本中,消息会在发送消息的脚本中被接收。如果您希望您的扩展程序在该版本或更早版本中使用,您必须考虑到这种可能性(即忽略它们),因为某些情况可能会导致 Firefox 锁定(例如,如果您总是发送新消息)当您收到消息时)。
关于javascript - 所有在后台上下文中发送给一个脚本的消息都会被接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44804009/
我是一名优秀的程序员,十分优秀!