chrome.extension.onMessage.addListener Cannot read property 'onMessage' of undefined

In the background.html:

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

In the content.js:

chrome.extension.onMessage.addListener(function(msg,sender,sendResponse){
  if (msg == "target.js"){
    extensionID = sender.id;
  }
});

However, it doesn't work;

Uncaught TypeError: Cannot read property 'onMessage' of undefined 

How to make it right?


You said "content.js is a content script and it is injected to the current tab by another content script.".

Herein lies your problem. Injected scripts are executed in the context of a page (as if they were created by the page itself), and therefore they have no access to any of the Chrome extension APIs.

You could use a custom event or postMessage to communicate between the page and your content script, which in turn communicates with the background page.

For instance, see this basic example:

    // Injected script script
    addEventListener('message', function(event) {
        if (event.data && event.data.extensionMessage) {
            alert(event.data.extensionMessage);
        }
    });
    // Content script which injects the script:
    chrome.extension.onMessage.addListener(function(message) {
        postMessage({extensionMessage: message}, '*');
    });

I think that you want to use content.js as a real content script though, rather than an injected script. If you want to know the differences between injected scripts and content scripts, see Chrome extension code vs Content scripts vs Injected scripts.