Search code examples
google-chromegoogle-chrome-extensioncontent-script

onClick communication between content and background scripts not working


I am making an application that highlights key words in the current page after the user clicks my icon. I am trying to communicate between my content scripts and background script. However,my code is not working. Does anyone know how it should be written?

Here is my content script:

chrome.extension.onRequest.addListener(function(active,sender,sendResponse){
if(active.length>0){
jQuery(document).ready(function($) {
//rest of word highlighting code
}
})

here is my background.js :

chrome.browserAction.onClicked.addListener(function(tab) {

  chrome.extension.sendRequest(active);

});

Solution

    1. Do not use the deprecated chrome.extension.sendRequest and matching events. They are old, broken and not supported, which is quite clearly said in the documentation - which shows that you did not go and read it.

      The correct ones to use are chrome.runtime.sendMessage and .onMessage, but otherwise the signature is the same.

    2. Well.. Why did you expect that to work? (unless you're not really showing us all relevant code, which is.. not helpful)

      chrome.browserAction.onClicked.addListener(function(tab) {
      
        // There is no "active" in the code anywhere to this point.
        //   It is treated like a variable name, one that was not yet used,
        //   so its contents are "undefined", and that's what you're sending.
        chrome.runtime.sendMessage(active);
        // Equivalent code: chrome.runtime.sendMessage(undefined);
      
      });
      

      And on the receiving side:

      chrome.runtime.onMessage.addListener(function(active,sender,sendResponse){
        // So, here "active" is undefined. It does not have a length
        //   parameter, and as such causes a fatal exception
        //   "Cannot read property 'length' of undefined"
        //   that you might have seen in the console of the page
        if(active.length>0){
          /* something */ 
        }
      })
      

    Whatever you send is usually, but not always, an object (well, it must be JSON-serializable). If you just want to trigger something and not pass any data, there are 2 often-used conventions, either is fine:

    1. Pass command as a value.

      // Sender
      chrome.runtime.sendMessage({action: "active"});
      // Receiver
      chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
        if(message.command == "active"){
          /* something */ 
        }
      
        // or, useful if you have many different commands:
      
        switch(message.command){
          case "active":
            /* something */
            break;
        }
      });
      
    2. Set a boolean in the message:

      // Sender
      chrome.runtime.sendMessage({active: true});
      // Receiver
      chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
        if(message.active){
          /* something */ 
        }
      });