简体   繁体   中英

How to pass message from popup script to background script to content script

EDIT -- added background script

I need to get a message from the popup script in my chrome extension to the content script. It should send the message when a button inside the popup is clicked.

After reading more, it seems like you can't communicate directly between the popup script and the content script.

I think I need to go: popup.js > background.js > script.js

I've tried doing this, but I can't seem to get it to work. There are a couple different ways to implement message passing, but not much documentation for this use case.

here's the code (it doesn't seem to pass a message at all right now):

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"
  }
}

right now this is doing nothing -- no alert message pops up and nothing is printed to the console when I pressed the button with the click event.

This is how it should run:

1) User enters input into popup window 'save-button' and clicks save

2) onclick of the save-button, input is saved in localstorage (this part works)

3) onclick of the save-button, message is sent from popup.js to script.js telling it that new input has been saved to localstorage

4) Script.js receives message and prints to the regular console "message passed"

The reason I'm doing this is that I need to make the content script do some logic when it receives notice that new input has been saved in local storage. Does this seem reasonable?

You can actually go directly from popup.js > script.js since the background page's messaging api is accessible to the popup too.

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": ["<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!"});
});

A very important permission for message passing ie tabs which is used to interact with the browser's tab system, is missing in your permission list.

Replace permissions array in manifest.json with

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM