无法从后台脚本在标签上接收消息

时间:2018-10-15 13:29:04

标签: javascript firefox-webextensions

我编写了此脚本,以将消息从后台脚本发送到新选项卡中的脚本,但是由于某种原因,选项卡中的脚本未收到消息。这是我的脚本或浏览器(Firefox 62.0.3)的问题

我的“清单”:

{
"manifest_version":2,
"name": "test",
"version": "1.0",
"description": "this is a test extension",

"background":{
"scripts": ["OnButtonClick.js"]
},

"permissions": [

 "tabs"

],

"content_scripts": [{

"matches": ["www.youtube.com"],
"js": ["input.js"]

}],

"browser_action": {

"default_icon": "button.png",
"default_title": "test button"
}

}

我的“ OnButtonClick.js”:

function action(){

  browser.tabs.create({
    url: "www.youtube.com"  
});

browser.tabs.sendMessage(1,{"message":"hi"})

}

browser.browserAction.onClicked.addListener(action);

和我的“ input.js”:

function handleMessage(msg){
    console.log(msg);

}

 browser.runtime.onMessage.addListener(handleMessage)

2 个答案:

答案 0 :(得分:1)

browser.tabs.create()是异步的,因此browser.tabs.sendMessage()甚至在创建选项卡之前就运行。

您必须等待它首先运行。

以下是一些建议:

// first create the tab 
const newTab = browser.tabs.create({
  url: 'https://example.org'
});
newTAb.then(onCreated, onError);

// after tab is created 
function onCreated(tab) {
  browser.tabs.sendMessage(tab.id,{message: 'hi'});
}
// in case of error
function onError(error) {
  console.log(`Error: ${error}`);
}

// above can also be written as this
browser.tabs.create({
  url: 'https://example.org'
}).then(
  tab => browser.tabs.sendMessage(tab.id,{message: 'hi'}),
  error => console.log(error)
); 

// another alternative for above
browser.tabs.create({url: 'https://example.org'})
.then(tab => browser.tabs.sendMessage(tab.id,{message: 'hi'}))
.catch(error => console.log(error));

// Using chrome and callback function
chrome.tabs.create({url: 'https://example.org'}, tab =>
  browser.tabs.sendMessage(tab.id,{message: 'hi'})
);

// same as above, all with chrome
chrome.tabs.create({url: 'https://example.org'}, tab =>
  chrome.tabs.sendMessage(tab.id,{message: 'hi'})
);

您也可以使用async/await,但是在这种情况下,这可能会使操作更加复杂。

评论更新:
content_scripts默认运行在"document_idle"(对应于完成。文档及其所有资源的加载已完成。)

"content_scripts": [{
  "matches": ["www.youtube.com"],
  "js": ["input.js"]
}],

因此,一旦装入所有内容,就会注入input.js。但是,sendMessage()一经创建选项卡便立即运行,因此没有侦听器可以收听其消息。

在您的简单示例中,可以通过"run_at": "document_start"

进行修复
"content_scripts": [{
  "matches": ["www.youtube.com"],
  "js": ["input.js"],
  "run_at": "document_start"
}],

但是,如果input.js在收到消息后需要访问DOM,则需要添加DOMContentLoadedload侦听器并在文档加载后运行它。

答案 1 :(得分:0)

为什么要使用“ sendMessage”? 您可以使用此代码

browser.tabs.executeScript(tabID, {    code: "func()" /* your function in content script*/,frameId:0 /* for send to all frame or put id for use a special frame id*/});

或将此代码作为文件

browser.tabs.executeScript(tabID, {    file: "/filename.js",frameId:0});