chrome.tabs.executeScript not working?

I am trying to learn to use the chrome.tabs.executeScript commend. I've created a simple extension with a browser action. My background.html file currently looks like this:

<html>
<script>
    chrome.browserAction.onClicked.addListener(function(tab) {
        chrome.tabs.executeScript(null,{code:"document.body.bgColor='red'"});
        chrome.tabs.executeScript(null, {file: "content_script.js"});
    });
</script>
</html>

The "content_script.js" file contains document.body.bgColor='red'.

When pushing the browser action's button nothing happens. Obviously I'm missing something very basic.

I've checked with console.log that indeed control reaches the chrome.tabs.executeScript calls when the browser action is pressed. Otherwise I'm not sure how to even check if my content script's code is run (it seems not; console.log I put in the content script has no effect, but maybe it shouldn't have one even if the script is run successfully).


Make sure you have domain and tab permissions in the manifest:

"permissions": [
    "tabs", "http://*/*", "https://*/*"
]

Then to change body color try:

chrome.tabs.executeScript(null,{code:"document.body.style.backgroundColor='red'"});

Also keep in mind that content scripts are not injected into any chrome:// or extension gallery pages.


For those of you still having issues, you need to make sure to reload the extension's permissions in Chrome.

Go to chrome://extensions , scroll to your extension, and click on "reload". Make sure that your permissions have been updated by clicking on the permissions link right next to your extension.


You actually don't need and don't want the 'tabs' permission for executeScript.

"permissions": [
  "http://*/*", 
  "https://*/*"
]

Should be enough.


It's not recommended to use http://*/* and https://*/*. From the Google documentation:

To inject a programmatic content script, provide the activeTab permission in the manifest. This grants secure access to the active site's host and temporary access to the tabs permission, enabling the content script to run on the current active tab without specifying cross-origin permissions.

Instead, (as suggested in the page) just use activeTab permission.


Remark: more explanation for the security issue

Without activeTab, this extension would need to request full, persistent access to every web site, just so that it could do its work if it happened to be called upon by the user. This is a lot of power to entrust to such a simple extension. And if the extension is ever compromised, the attacker gets access to everything the extension had.

In contrast, an extension with the activeTab permission only obtains access to a tab in response to an explicit user gesture. If the extension is compromised the attacker would need to wait for the user to invoke the extension before obtaining access. And that access only lasts until the tab is navigated or is closed.

(emphasis mine)

In the example code posted by the OP, activeTab is sufficient.

However, if the extension is more complex and needs to work "automatically" (i.e. without the user clicking the button); then this method will not work and additional permission is required.