【问题标题】:How to pass message from popup script to background script to content script如何将消息从弹出脚本传递到后台脚本到内容脚本
【发布时间】:2016-06-17 22:41:43
【问题描述】:

编辑——添加后台脚本

我需要从我的 chrome 扩展中的弹出脚本中获取一条消息到内容脚本。它应该在单击弹出窗口内的按钮时发送消息。

阅读更多内容后,您似乎无法在弹出脚本和内容脚本之间直接通信。

我想我需要去: popup.js > background.js > script.js

我试过这样做,但我似乎无法让它工作。有几种不同的方式来实现消息传递,但是对于这个用例没有太多的文档。

这是代码(它现在似乎根本没有传递消息):

popup.js

/* when something is saved in local storage... */
        chrome.storage.sync.set({'myFilter': filter}, function(){

            /* send message to background script */
            chrome.runtime.sendMessage({greeting: "hello from popup"}, function(response) {
                console.log(response.farewell);
            });
            chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
              chrome.tabs.sendMessage(tabs[0].id, {greeting: "new filter saved"}, function(response) {
                console.log(response.farewell);

              });
            });
        });

background.js

 /*listen for message from popup, send message to content script */
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a background script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello from popup") {
        alert("message passed to background script");
        console.log("message passed to background script");

         /* send message to content script */
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
                  chrome.tabs.sendMessage(tabs[0].id, {greeting: "popup sent message"}, function(response) {
                    console.log(response.farewell);

                  });
                });
         return true;
       sendResponse({farewell: "goodbye"});
    }
    return false;
  });

script.js

    /* get notice from background script*/
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "popup sent message") {
        alert("message passed to content script");
        console.log("message passed to content script");
        location.reload();
        walkWithFilter();
         return true;
       sendResponse({farewell: "goodbye"});
    }
    return false;
  });

manifest.json

{
  "manifest_version": 2,
  "name": "filter",
  "description": "This extension allows twitter users to filter content in their feed",
  "version": "1.0",
  "content_scripts": 
  [
    {
      "matches": ["*://*/*"],
      "js": ["bower_components/jquery/dist/jquery.min.js", "script.js"],
      "run_at": "document_end"
    }
  ],

  "permissions": [
    "tabs",
    "storage",
    "contextMenus",
    "background",
    "https://twitter.com/",
    "http://twitter.com/"  
  ],

  "icons": {
    "16": "fa-moon.png"
  },

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

  "browser_action": {       
   "default_title": "filter",
    "default_icon": "fa-moon.png",
    "default_popup": "popup.html"
  }
}

现在这什么也没做——当我按下带有 click 事件的按钮时,不会弹出任何警报消息,也不会向控制台打印任何内容。

它应该是这样运行的:

1) 用户在弹出窗口“保存按钮”中输入输入并点击保存

2)点击保存按钮,输入保存在本地存储中(这部分有效)

3) onclick 保存按钮,消息从 popup.js 发送到 script.js 告诉 新输入已保存到本地存储

4) Script.js 接收消息并打印到常规控制台“消息传递”

我这样做的原因是我需要让内容脚本在收到新输入已保存在本地存储中的通知时执行一些逻辑。这看起来合理吗?

【问题讨论】:

  • “保存按钮”在哪里?是在当前网页还是只是弹出页面?
  • 查看stackoverflow.com/questions/36107503/… 以调试您看不到console.logs 的原因。
  • 我的直觉说你的问题是onclick,你应该看看stackoverflow.com/q/13591983/2336725
  • @HibaraAi 保存按钮是弹出窗口中的一个按钮。您可以输入文本,然后将其保存到本地存储(这部分工作)
  • 您无法从弹出窗口向内容脚本发送消息的假设是错误:您可以直接从弹出窗口向内容脚本发送消息内容脚本。 popup.js 是如何加载的?您是否知道,如果您硬重新加载扩展程序,现有的内容脚本在页面重新加载之前无法与您的扩展程序通信?

标签: javascript jquery dom google-chrome-extension message-passing


【解决方案1】:

您实际上可以直接从 popup.js > script.js 因为弹出窗口也可以访问后台页面的消息传递 API。

ma​​nifest.json

{
  "manifest_version": 2,
  "name": "filter",
  "description": "This extension allows twitter users to filter content in their feed",
  "version": "1.0",
  "content_scripts": 
  [
    {
      "matches": ["<all_urls>"],
      "js": ["script.js"],
      "run_at": "document_end"
    }
  ],

  "permissions": [
    "tabs",
    "storage",
    "contextMenus",
    "background",
    "https://twitter.com/",
    "http://twitter.com/"  
  ],

  "icons": {
  },

  "background": {
    "scripts": []
  },

  "browser_action": {       
    "default_title": "filter",
    "default_popup": "popup.html"
  }
}

popup.html

<button id="save-button">save-button</button>
<script src="/popup.js" type='text/javascript'></script>

popup.js

document.getElementById("save-button").onclick = function(){
    console.log("clicked button");

    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        if(tabs.length == 0){ 
            console.log("could not send mesage to current tab");
        }else{
            chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello, how are you content script?"}, function(response) {
                console.log("received message from content script: "+response.farewell);
            });
        }
    });
}

script.js

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");


    console.log("received message from popup: "+request.greeting);

    sendResponse({farewell: "I'm good, thank you popup!"});
});

【讨论】:

  • 终于让它发送消息了!消息发送后我收到此错误:extensions::uncaught_exception_handler:8 runtime.onMessage 的事件处理程序出错:错误:尝试在 chrome-extension://nbcngiipoendfnhjhjgbpkaiecjidagb/script.js:49 使用断开连接的端口对象: 5
  • 我很高兴它对你有用 :) 这个错误不是来自我的示例脚本,因为它在我测试它时工作正常。该错误消息必须来自未正确使用 chrome.tabs.connect() api 的 script.js 的另一部分。在谷歌上查找错误。
  • 你能看到 OP 做错了什么吗?我没有,我没有看到你做了什么改变。
【解决方案2】:

您的权限列表中缺少一个非常重要的消息传递权限,即tabs,该权限用于与浏览器的标签系统交互。

将 manifest.json 中的权限数组替换为

"permissions": [
    "tabs",
    "storage",
    "contextMenus",
    "background",
    "https://twitter.com/",
    "http://twitter.com/"  
  ],

【讨论】:

  • 谢谢补充!你能想出一个更好的方法来测试消息传递是否有效吗?我仍然没有看到 console.log,但也许有更好的方法来测试消息是否从弹出窗口传递到内容脚本
  • 只有当 OP 想要读取 urltitlefaviconUrl 属性时才需要 tabs 权限,这里似乎不是这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-16
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多