为什么插件页面收不到消息?
Why cannot the addon page receive message?
我正在尝试从插件(webextension)向插件中的 html 页面发送消息。 Webextension API 正在使用与 Chrome 浏览器兼容的 chrome 界面。我正在使用 Firefox 48 测试版。
这是后台脚本("initiate-page" 消息很重要):
chrome.runtime.onMessage.addListener(
function(package, sender
){
switch (package.message){
case "open":
if (package.subject == "tab")
{
win = myNamespace.tabs[package.module];
result = win ? false : true;
if (result)
chrome.tabs.create(
{"url": package.url },
function(tab) {
if (chrome.extension.lastError )
console.log(chrome.extension.lastError);
else
myNamespace.tabs[package.module] = tab.id;
chrome.tabs.onRemoved.addListener(
function( tabId, removeInfo )
{
for (var k in myNamespace.tabs )
{
if (tabId === myNamespace.tabs[k])
{
myNamespace.tabs[k] = null;
break;
}
}
}
);
}
);
}
break;
case "initiate-page":
if (package.subject == "html-add-listeners")
{
switch(package.module){
case "easy_options":
case "advanced_options":
case "images_options":
chrome.tabs.sendMessage(
package.sender.id,
{ message:"initiate-page-response",
subject:"accept-namespace",
recepient: {id: package.sender.id },
module: package.module,
namespace: myNamespace,
info: "response to tab exists message"
}
)
break;
}
}
break;
}
}
)
因此,当插件收到来自模块 "easy_options" 的消息时,这意味着 easy_options.html 需要一些数据来加载到其文档中。因此,我发送了一条包含数据的名称空间的消息。
现在是插件页面 easy_options.js(同样,第二部分很重要,其中添加了 chrome.runtime.onMessage 侦听器):
chrome.tabs.query(
{ active: true, currentWindow: true},
function(tabs) {
browser.runtime.sendMessage(
{ message:"initiate-page",
subject: "html-add-listeners",
module: "easy_options",
sender:{id:tabs[0].id}
}
)
}
);
chrome.runtime.onMessage.addListener(
function(package, sender
){
switch (package.message){
case "initiate-page-response":
if (package.subject == "accept-namespace")
{
switch(package.module){
case "easy_options":
document.addEventListener('DOMContentLoaded', myNamespace.easy.restore);
document.getElementById("easy_form_save").addEventListener("submit", myNamespace.easy.save);
document.getElementById("easy_form_restore").addEventListener("submit", myNamespace.easy.restore);
document.getElementById("easy_form_remove_item").addEventListener("submit", myNamespace.easy.remove_profiles);
document.getElementById("easy_form_remove_profiles").addEventListener("submit", myNamespace.easy.remove_profiles);
document.getElementById("list").addEventListener("change", myNamespace.easy.restoreDefault);
break;
}
}
break;
}
}
)
发生的事情是:
1. 我向后台侦听器发送消息 (A),它接受该消息
2.后台监听发送消息(B)
3. 插件选项脚本在 runtime.OnMessage 侦听器中接收第一条消息 (A)(我不想处理此消息)
应该发生什么
1. 我向后台侦听器发送消息 (A),它接受该消息
2.后台监听发送消息(B)
3. 插件选项脚本在 runtime.OnMessage 侦听器中接收到第一条消息 (A)(我不想处理这条消息)
4. 插件选项脚本应该在 runtime.OnMessage 侦听器中接收第二条消息 (B),我应该处理它
问题:
为什么第四步没有发生?为什么收不到消息(B别名"initiate-page-response")?
也许 Chrome 插件程序员也可以提供帮助,我认为事情应该类似地工作。
因为它是一个扩展页面,而不是内容脚本,chrome.tabs.sendMessage
无法访问它。
您需要使用 chrome.runtime.sendMessage
广播消息才能到达 chrome-extension://
个页面,例如选项页面。
如果您不喜欢 runtime.sendMessage
的广播性质,您应该使用 sendResponse
回调参数将响应传回给发送者(可能更可取),或者建立一个长期存在的端口runtime.connect
.
感谢 Xan 的解释,我发现这很有魅力
后台脚本:
chrome.runtime.onMessage.addListener(
function(package, sender, sendResponse
){
switch (package.message){
case "open":
if (package.subject == "tab")
{
win = myNamespace.tabs[package.module];
result = win ? false : true;
if (result)
chrome.tabs.create(
{"url": package.url },
function(tab) {
if (chrome.extension.lastError )
console.log(chrome.extension.lastError);
else
myNamespace.tabs[package.module] = tab.id;
chrome.tabs.onRemoved.addListener(
function( tabId, removeInfo )
{
for (var k in myNamespace.tabs )
{
if (tabId === myNamespace.tabs[k])
{
myNamespace.tabs[k] = null;
break;
}
}
}
);
}
);
}
break;
case "initiate-page":
if (package.subject == "html-add-listeners")
{
switch(package.module){
case "easy_options":
case "advanced_options":
case "images_options":
sendResponse(
{ message:"initiate-page-response",
subject:"accept-namespace",
recepient: {id: package.sender.id },
module: package.module,
namespace: myNamespace,
info: "response to initiate-page message"
}
)
break;
}
}
break;
}
}
)
插件的选项页面脚本:
chrome.tabs.query(
{ active: true, currentWindow: true},
function(tabs) {
browser.runtime.sendMessage(
{ message:"initiate-page",
subject: "html-add-listeners",
module: "easy_options",
sender:{id:tabs[0].id}
},
function response(message){
console.log("RESPONSE:");
console.log(message);
return true;
}
)
}
);
我正在尝试从插件(webextension)向插件中的 html 页面发送消息。 Webextension API 正在使用与 Chrome 浏览器兼容的 chrome 界面。我正在使用 Firefox 48 测试版。
这是后台脚本("initiate-page" 消息很重要):
chrome.runtime.onMessage.addListener(
function(package, sender
){
switch (package.message){
case "open":
if (package.subject == "tab")
{
win = myNamespace.tabs[package.module];
result = win ? false : true;
if (result)
chrome.tabs.create(
{"url": package.url },
function(tab) {
if (chrome.extension.lastError )
console.log(chrome.extension.lastError);
else
myNamespace.tabs[package.module] = tab.id;
chrome.tabs.onRemoved.addListener(
function( tabId, removeInfo )
{
for (var k in myNamespace.tabs )
{
if (tabId === myNamespace.tabs[k])
{
myNamespace.tabs[k] = null;
break;
}
}
}
);
}
);
}
break;
case "initiate-page":
if (package.subject == "html-add-listeners")
{
switch(package.module){
case "easy_options":
case "advanced_options":
case "images_options":
chrome.tabs.sendMessage(
package.sender.id,
{ message:"initiate-page-response",
subject:"accept-namespace",
recepient: {id: package.sender.id },
module: package.module,
namespace: myNamespace,
info: "response to tab exists message"
}
)
break;
}
}
break;
}
}
)
因此,当插件收到来自模块 "easy_options" 的消息时,这意味着 easy_options.html 需要一些数据来加载到其文档中。因此,我发送了一条包含数据的名称空间的消息。
现在是插件页面 easy_options.js(同样,第二部分很重要,其中添加了 chrome.runtime.onMessage 侦听器):
chrome.tabs.query(
{ active: true, currentWindow: true},
function(tabs) {
browser.runtime.sendMessage(
{ message:"initiate-page",
subject: "html-add-listeners",
module: "easy_options",
sender:{id:tabs[0].id}
}
)
}
);
chrome.runtime.onMessage.addListener(
function(package, sender
){
switch (package.message){
case "initiate-page-response":
if (package.subject == "accept-namespace")
{
switch(package.module){
case "easy_options":
document.addEventListener('DOMContentLoaded', myNamespace.easy.restore);
document.getElementById("easy_form_save").addEventListener("submit", myNamespace.easy.save);
document.getElementById("easy_form_restore").addEventListener("submit", myNamespace.easy.restore);
document.getElementById("easy_form_remove_item").addEventListener("submit", myNamespace.easy.remove_profiles);
document.getElementById("easy_form_remove_profiles").addEventListener("submit", myNamespace.easy.remove_profiles);
document.getElementById("list").addEventListener("change", myNamespace.easy.restoreDefault);
break;
}
}
break;
}
}
)
发生的事情是: 1. 我向后台侦听器发送消息 (A),它接受该消息 2.后台监听发送消息(B) 3. 插件选项脚本在 runtime.OnMessage 侦听器中接收第一条消息 (A)(我不想处理此消息)
应该发生什么 1. 我向后台侦听器发送消息 (A),它接受该消息 2.后台监听发送消息(B) 3. 插件选项脚本在 runtime.OnMessage 侦听器中接收到第一条消息 (A)(我不想处理这条消息) 4. 插件选项脚本应该在 runtime.OnMessage 侦听器中接收第二条消息 (B),我应该处理它
问题: 为什么第四步没有发生?为什么收不到消息(B别名"initiate-page-response")?
也许 Chrome 插件程序员也可以提供帮助,我认为事情应该类似地工作。
因为它是一个扩展页面,而不是内容脚本,chrome.tabs.sendMessage
无法访问它。
您需要使用 chrome.runtime.sendMessage
广播消息才能到达 chrome-extension://
个页面,例如选项页面。
如果您不喜欢 runtime.sendMessage
的广播性质,您应该使用 sendResponse
回调参数将响应传回给发送者(可能更可取),或者建立一个长期存在的端口runtime.connect
.
感谢 Xan 的解释,我发现这很有魅力
后台脚本:
chrome.runtime.onMessage.addListener(
function(package, sender, sendResponse
){
switch (package.message){
case "open":
if (package.subject == "tab")
{
win = myNamespace.tabs[package.module];
result = win ? false : true;
if (result)
chrome.tabs.create(
{"url": package.url },
function(tab) {
if (chrome.extension.lastError )
console.log(chrome.extension.lastError);
else
myNamespace.tabs[package.module] = tab.id;
chrome.tabs.onRemoved.addListener(
function( tabId, removeInfo )
{
for (var k in myNamespace.tabs )
{
if (tabId === myNamespace.tabs[k])
{
myNamespace.tabs[k] = null;
break;
}
}
}
);
}
);
}
break;
case "initiate-page":
if (package.subject == "html-add-listeners")
{
switch(package.module){
case "easy_options":
case "advanced_options":
case "images_options":
sendResponse(
{ message:"initiate-page-response",
subject:"accept-namespace",
recepient: {id: package.sender.id },
module: package.module,
namespace: myNamespace,
info: "response to initiate-page message"
}
)
break;
}
}
break;
}
}
)
插件的选项页面脚本:
chrome.tabs.query(
{ active: true, currentWindow: true},
function(tabs) {
browser.runtime.sendMessage(
{ message:"initiate-page",
subject: "html-add-listeners",
module: "easy_options",
sender:{id:tabs[0].id}
},
function response(message){
console.log("RESPONSE:");
console.log(message);
return true;
}
)
}
);