carter
carter

Reputation: 5432

Send message from background script to content script then response in chrome extension

I am trying to make a chrome extension. My background script fires on a button press in the ui. It should send a message to my content script, which is going to send a response back to the background script. Can't quite figure out how this is supposed to work. The click listener is firing, but the messaging does not work. Here is what I got so far:

Background Script:

$(document).on('click', '#getGlobalFuncsBtn', function(){
    chrome.extension.sendMessage({text:"getStuff"},function(reponse){       
        if(reponse.type == "test"){
            console.log('test received');
        }
    });
    console.log('click listener');
});

Content Script:

chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
    if(message.text == "getStuff"){
        console.log('test sent');
        sendResponse({type:"test"});
    }
});

Popup HTML:

<!DOCTYPE html>
<html>
<head>
</head>
<body>

<button id="getGlobalFuncsBtn">Get Global Funcs</button>

<script src="jquery-2.0.2.min.js"></script>
<script src="background.js"></script>
</body>
</html>

manifest.json:

{
  "manifest_version": 2,

  "name": "Var Viewer",
  "description": "This extension allows you to view and change all user defined js global vars.",
  "version": "1.1",
  "permissions": [
    "storage"
  ],
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["jquery-2.0.2.min.js","content.js"]
    }
  ],
  "web_accessible_resources": [
    "jquery-2.0.2.min.js"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": true
  },
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "pop.html",
    "default_title": "Var Viewer"
  }
}

Upvotes: 1

Views: 10267

Answers (1)

gthacoder
gthacoder

Reputation: 2351

1) First of all, you are trying to trigger getGlobalFuncsBtn button click event inside background script, which is pointless. Actually, you are declaring background.js two times: first time inside manifest file:

"background": {
  "scripts": ["jquery-1.7.2.min.js","background.js"]
},

(which means it is a background script)

, second time inside popup.html:

<script src="background.js"></script>

(which means it is a popup JavaScript file)

Background page is a place where you only perform some background actions (for example, calculations). popup.html is your actual popup window, so that is a place when you should work with button using jQuery. Overall, you should just erase background field in manifest.json (and it would be great to rename background.js to something like popup.js, but it is not necessary).

(Your background script fires on a button press because you declared it once properly - inside popup.html.)

You can read more about background pages in the official documentation: http://developer.chrome.com/extensions/background_pages.html.

2) Your second problem is with the message sending between extension page (it could be any extension page, in your code snippets it is background.js) and content script. If you want to set communication channel between two regular extension pages, it is pretty straightforward. Use chrome.runtime.sendMessage and chrome.runtime.onMessage.addListener. However, if you want to communicate with content script, you have to use slightly more complicated by defining the particular tab you are sending message to (content script is actually executed as a part of the code of tab you specified in manifest file). You code should be something like this:

in background.js (or popup.js if you rename it):

// code below is supposed to be inside your button trigger
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {text:"getStuff"}, function(response) {
    if(response.type == "test"){
      console.log('test received');
    }
  });
});

Content script event listener looks the same for extension page or content script, so your content.js code should work properly as it is. You only need to replace extension with runtime:

in content.js:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.text == "getStuff") {
      console.log('test sent');
      sendResponse({type: "test"});
    }
});

Nice read about the message passing in Chrome extension: http://developer.chrome.com/extensions/messaging.html.

Upvotes: 7

Related Questions