Search code examples
javascriptgoogle-chrome-extensionmessage-passing

Chrome Message Passing API does not work


I'm trying to create an extension which tells me if a certain script is used on the current website I'm displaying in a tab.

I have a content script to see which scripts are used an to send messages to the my background script, which handles notification if a tab is switched and changes the icon of my extension to see if scripts are used or not.

This is my content script (load.js):

chrome.runtime.sendMessage({script_found: checkScript()});
function checkScript() {
    var script_found = true;
    var length = document.getElementsByTagName("script").length;

    for (var i = 0; i < length; i++) { 
        var list = document.getElementsByTagName("script")[i].src;
        var t = list.toString();
        if (t.length > 1) {
            if((t.indexOf("edge") != -1) || (t.indexOf("prototype") != -1)) {
                script_found = false;
            }
        }
    }

    return script_found;
}

chrome.runtime.onMessage.addListener(
  function(request, sendResponse) {
    if(request.tabSwitch == true) {
        sendResponse({script_found: checkScript()});
    }
});

This is my background service (background.js):

chrome.tabs.onActivated.addListener(tabSwitch);

function tabSwitch() {
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, {tabSwitch: "true"},function(response) {
            refreshIcon(response.script_found);
        });
    });
}

chrome.runtime.onMessage.addListener(
  function(request) {
    refreshIcon(request.script_found);
  });


function refreshIcon(script_found) {
    if(script_found) {
        chrome.browserAction.setIcon({path:"good.png"})
    } else if(!script_found) {
        chrome.browserAction.setIcon({path:"error.png"})
    }
}

I really do not know why it is not working on tabSwitch. It works fine when a website is loaded but it won't when I switch between tabs.

I hope you can help! Thanks in advance!!

EDIT: This is my manifest (manifest.json):

{
  "manifest_version": 2,

  "name": "Script Hunter",
  "description": "This extension shows if certain scripts are used on this page.",
  "version": "1.0",

  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["load.js"],
    "run_at": "document_idle"
  }],

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

  "browser_action": {
    "default_icon": "good.png"
  },

  "permissions": [
    "tabs",
    "activeTab",
    "https://ajax.googleapis.com/"
  ]
}

Thanks once again!


Solution

    1. For background.js, you don't need to query active tab, you could just use the callback parameter of chrome.tabs.onActivated. (As @wOxxOm has mentioned in the comments, use tabSwitch: true here)

      chrome.tabs.onActivated.addListener(tabSwitch);
      
      function tabSwitch(activeInfo) {
          chrome.tabs.sendMessage(activeInfo.tabId, {tabSwitch: true},function(response) {
              refreshIcon(response.script_found);
          });
      }
      
    2. In load.js, the third parameter for the callback of chrome.runtime.onMessage is sendResponse, however you only specify two parameters.

      chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
          ...
      });