49

I'm trying to get my Chrome Extension to inject some javascript with content_scripts, using this previous answer as a reference.

manifest.json

"name": "My Chrome Extension",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [{
    "matches": ["http://pagetoinject/script/into/*"],
    "js": ["contentscript.js"]
}]  

contenscript.js:

var s = document.createElement('script');
s.src = chrome.extension.getURL("script.js");
(document.head||document.documentElement).appendChild(s);
s.parentNode.removeChild(s);

( also tried this method with no success. )

var s = document.createElement('script');
s.src = chrome.extension.getURL("script.js");
s.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);

I keep getting this javascript error. Here's a screenshot.

enter image description here GET chrome-extension://invalid/ (anonymous function)

Community
  • 1
  • 1
Nick Fury
  • 1,313
  • 3
  • 13
  • 23
  • Not sure what is happening, but why don't you do this instead: `"js": ["contentscript.js","script.js"]` – Derek 朕會功夫 May 10 '12 at 05:49
  • 1
    Because `content_scripts` are executed in an isolated environment. I need to inject the `script.js` into the DOM so I can use that file as if it was part of the public js folder. It's explained in the first section of [this answer](http://stackoverflow.com/questions/9515704/building-a-chrome-extension-inject-code-in-a-page-using-a-content-script) – Nick Fury May 10 '12 at 06:04
  • [This answer](http://stackoverflow.com/questions/4578761/showing-several-js-variables-value-in-chrome-extensions) does what you are trying to in the content script. It might be what you're looking for. – Sparragus May 17 '12 at 00:48

5 Answers5

109
  1. In your manifest file, "manifest_version": 2 is specified. This automatically activates a stricter mode, in which all extension's files are not available to web pages by default.
  2. Your original code would never work, because the <script> element is immediately removed after injection (the script file does not have a chance to load).

As a result of 1., the following error shows up in the console:

Failed to load resource                             chrome-extension://invalid/

To fix the problem, add script.js to the whitelist, "web_accessible_resources" in your manifest file:

{
  "name": "Chrome Extension",
  "version": "1.0",
  "manifest_version": 2,
  "content_scripts": [{
      "matches": ["http://pagetoinject/script/into/*"],
      "js": ["contentscript.js"]
  }],
  "web_accessible_resources": ["script.js"]
}
zessx
  • 68,042
  • 28
  • 135
  • 158
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks for the great response everything worked exactly as mentioned. Also thanks for the orginal code from [here](http://stackoverflow.com/questions/9263671/google-chome-application-shortcut-how-to-auto-load-javascript/9310273#9310273) – Nick Fury May 10 '12 at 18:54
  • but is there a way to modify a property of `window` from a script injected this way (or any other way)? – YakovL Feb 07 '20 at 13:01
  • i have tried a lot but this is the only answer that works for me – Hiệp Nguyễn Apr 26 '20 at 18:34
1

In addition to the answers above I notice that in your contentscript.js you are just adding another script i.e script.js Why don't you directly add script.js through content_scripts in manifest.json.

0

Another reason for getting this error is if the url is being blocked by CORS. Check the network request header of the page to see if it contains Content-Security-Policy:

Content-Security-Policy: default-src 'self' http://example.com; connect-src http://example.com/; script-src http://example.com/

You can try opening the url in a new browser tab to verify the image url is correct:

chrome-extension://mjcbjlencnokpknflpneebajalcnnifo/images/pattern.jpg

One way around this is to use an image data URI:

data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7
Kim T
  • 5,770
  • 1
  • 52
  • 79
0

Boilerplate for Chrome extension:

https://github.com/commanddotcom/boilerplate-chrome-extension-js-injection

Yevgen
  • 1,239
  • 3
  • 15
  • 30
-4

The problem here is that you are using manifest_version : 2. If you make that manifest-version: 1 you'll not have any problems. Version 2 restricts many such features to improve security. Refer Google Content Security Policy for more details on the restrictions imposed in manifest version 2. I could not find your specific case mentioned in the CSP but when I changed the manifest version to 1 and executed your code it is working fine.

Jophin Joseph
  • 2,864
  • 4
  • 27
  • 40