0

I'm attemtping to send a message from the content script to the background script, and send a response in return.

This is what I've got in my background script:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log("Message received");
    if(request.activeStatusRequest == "disable"){
      sendResponse({activeStatusUpdate: "disable"});
    }else if(request.activeStatusRequest == "enable"){
      sendResponse({activeStatusUpdate: "enable"});
    }
    return true;
});

This is what I've got in my content script:

printReviews.onclick = function(element) {
  if(printReviews.classList.contains("activeButton")){
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      chrome.tabs.executeScript(
          tabs[0].id,
          {code: `${injectionLiteralGETURL}`}
        );
    });

    toggleClasses(printReviews, "activeButton", "inactiveButton");

    chrome.runtime.sendMessage({activeStatusRequest: "disable"}, function(response){
      console.log("response received");
      console.log(response.activeStatusUpdate);
    });
  }
  else {
    toggleClasses(printReviews, "inactiveButton", "activeButton");
    chrome.runtime.sendMessage({activeStatusRequest: "enable"}, function(response){
      console.log("response received");
      console.log(response.activeStatusUpdate);
    });
  }
  };

The rest of the above code works as expected, except that the none of the console logs in the content script run. The console log in the background script does run, however. Anyone got any ideas as to what I've done wrong?

7
  • 1) You can't use chrome.tabs in a content script - only 3 or 4 basic API are allowed there. Move it to the background script. 2) No need for "return true" if you don't invoke sendResponse from an asynchronous call. 3) Start using devtools debugger where you can set breakpoints inside your code, execute it step by step and inspect the variables, state, DOM. 4) When you edit the content script code make sure to reload both the extension on chrome://extensions page and the web page so that the new code is injected. 5) If this is not helpful, please add manifest.json in the question. Commented Jan 24, 2019 at 17:16
  • @wOxxOm thanks for the reply. Im currently not at my computer and will make changes tomorrow. 1) that’s interesting. The injection of the code “injectionLiteralGETURL appears to work exactly as expected. Maybe I have the wrong idea of what a content script is? The file name of my “content script” is popup.js, and it is a script linked to my popup.html. 2) thanks, I’ll change this. 3) i was previously using this, but couldn’t seem to work out how it was going wrong. I’ll give it another go. 4) Yep, been doing this. 5) I’ll add the manifest.json when I’m back at my computer. Thanks for the help. Commented Jan 24, 2019 at 17:42
  • Indeed a browserAction popup script is not a content script so you can use chrome.tabs there. Commented Jan 24, 2019 at 17:44
  • So will I not be able to pass messages between these two scripts? Commented Jan 24, 2019 at 17:58
  • Assuming your background script is really a background script (that is properly declared in manifest.json), you can. A common mistake is loading the background script in the same popup.html. OTOH it's not clear why you need a background script at all since the popup script can do everything just as well. Commented Jan 24, 2019 at 18:20

1 Answer 1

1

If you want to try another method, you could try to add a listener in the content script

Content.js

    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        console.log("Message received  from background", response.type, response.activeStatusUpdate);
        switch(request.type){
            case 'SomeFirstAction'
                break;

            case 'SomeSecondAction'
                break;
        }

    });

Background.js

    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        console.log("Message received");
        if(request.activeStatusRequest == "disable"){
          sendMessageToCurrentTab({type: 'SomeFirstAction', activeStatusUpdate: "disable"});
        }else if(request.activeStatusRequest == "enable"){
          sendMessageToCurrentTab({type: 'SomeSecondAction', activeStatusUpdate: "enable"});
        }
        // return true; -> not needed with that method
    });


    function sendMessageToCurrentTab(message){
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.sendMessage(tabs[0].id, message);
        }
    }

To have played with callbacks between popup/background/content-script, I prefer just play with messages,because when using sendResponse, the manner it works, it open a port to communicate, but if something change (tab close, popup close), you will have an error because the port will be closed too. Using the 'Full send message manner', the background need to clearly target the receiver tab.

I also recommand you to use a type or some unique action attribute, because all listener will listen to all action. It will identify the action and it's purpose. Here I just used a switch in the content script, but the background could use the same logic.

Maybe it's not the greatest way of doing things, but it works well for me.

Hope this can help you

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.