Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome extension: load and execute external script

I have trouble loading and executing external js-script into my chrome extension. Looks the same as this question, but I still cant't figure out why it doesn't work in my case.

The idea is that I want to have in my content script some default function which should parse a web-page content. And for some specific web-pages I want to load and use specific parsers, so I try to load proper js-script for a wep-page, and this script shoud extend functionality of default parser.

By now I try only execute code from external script, but have such error: Unchecked runtime.lastError while running tabs.executeScript: No source code or file specified at Object.callback

This is my manifest.json:

{
"name": "Extension name",
"version": "1.2",
"description": "My chrome extension",
"browser_action": {
    "default_popup": "popup.html",
},
"content_scripts": [{
    "css": [
        "style.css"
    ],
    "js": [
        "bower_components/jquery/dist/jquery.js",
        "bower_components/bootstrap/dist/js/bootstrap.js",
        "content.js"
    ],
    "matches": ["*://*/*"]
}],
"web_accessible_resources": [
    "frame.html",
    "logo-48.png"
],
"icons": {
    "16": "logo-16.png",
    "48": "logo-48.png",
    "128": "logo-128.png"
},
"permissions": [
    "tabs",
    "storage",
    "http://*/",
    "https://*/"
],
"manifest_version": 2

}

This is popup.html

<!doctype html>
 <html>
 <head>
  <title>Title</title>
  <script src="popup.js"></script>
 </head>
 <body>
  <ul>
    <li>Some link</li>
  </ul>
 </body>
</html>

And in popup.js i execute scrip like this:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.executeScript(tabs[0].id, {file: "http://127.0.0.1:8000/static/plugin/somesite.js"});
});

What am I dong wrong, did I miss something? Or should I use another approach to solve the issue?

like image 264
jenush Avatar asked Jan 19 '15 08:01

jenush


2 Answers

Running scripts from external sources like you try is forbidden by google chrome and will block or even not publish your extension. All scripts must be in the extension. But there is a solution, from google chrome doc:

The restriction against resources loaded over HTTP applies only to those resources which are directly executed. You're still free, for example, to make XMLHTTPRequest connections to any origin you like; the default policy doesn't restrict connect-src or any of the other CSP directives in any way.

If you need badly an external source, you can do a XML HTTP request and use the eval to the content. Here is a part of code from google doc:

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://127.0.0.1:8000/static/plugin/somesite.js", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
      // WARNING! Might be evaluating an evil script!
      var resp = eval("(" + xhr.responseText + ")");
      // Or this if it's work
      chrome.tabs.executeScript(tabs[0].id, {code: xhr.responseText});
  }
}
xhr.send();

or you can use some library, $.get() with jquery or $http with angularjs. if you add eval in your code you must add in manifest.json this:

"content_security_policy":  "script-src 'self' 'unsafe-eval'; object-src 'self'"`,
like image 93
Thomas Karachristos Avatar answered Nov 09 '22 06:11

Thomas Karachristos


As per the discussion here: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/LIH7LGXeQHo,

Running scripts from external sources may cause your extension to be unpublished or blocked.

Just providing another approach, you could make an ajax call to the content script then call chrome.tabs.executeScript

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    $.get("http://127.0.0.1:8000/static/plugin/somesite.js", function(result) {
        chrome.tabs.executeScript(tabs[0].id, {code: result});
    }, "text");
});
like image 21
Haibara Ai Avatar answered Nov 09 '22 06:11

Haibara Ai