0

I'm trying to use a content script to inject my own JS files into a page. The way I'm trying to do this is based on the system used by a Chrome extension called dotjs, which runs a little server on your machine, and makes AJAX reuests to localhost in order to retrieve the files from that server.

I'm fairly certain those AJAX requests will only go through if they're sent from background.js rather than a content script, due to the Same Origin Policy. I also need to use webRequest, which again only works in a background page. But, since I need to inject the stuff into the page itself, I need a content script. So my extension works with a content script that sends messages to a background page, requesting that it do all the webRequest and AJAX that it needs.

The problem is, the messages don't seem to be getting received by background.js. I have some console.log()s in the onRequest handler in background.js as you can see, and they're not showing up in my console.

manifest.json

{
  "name": "dotjs",
  "version": "1.5",
  "description": "~/.js",
  "icons": { "48": "icon48.png",
            "128": "icon128.png" },
  "content_scripts": [{
    "all_frames": true,
    "run_at":     "document_start",
    "matches":    ["[censored]"],
    "js":         ["dotjs.js"]
  }],
  "background": {
    "scripts": ["jquery.js", "background.js"]
  },
  "permissions": ["tabs", "webRequest", "extension"]
}

dotjs.js

console.log("dotjs.js running");

var requestFilter =
    {
        url: "[censored]"
    };

var blockingResponse =
    {
        redirectUrl: "http://localhost:2262/Pigman/ips.chat.js"
    };  

function requestInterceptor(details)
{
    return blockingResponse;
}

chrome.extension.sendRequest(
    {
        type: "setListener",
        func: requestInterceptor,
        filter: requestFilter
    }
);

chrome.extension.sendRequest(
    {
        type: "loadJS",
        filename: "Elizabot/elizabot.js"
    },
    function (response) { eval(response); }
);

chrome.extension.sendRequest(
    {
        type: "loadJS",
        filename: "Elizabot/elizadata.js"
    },
    function (response) { eval(response); }
);

background.js

function loadJSFile(filename)
{
    $.ajax({
        url: 'http://localhost:2262/Pigman/' + filename + '.js',
        dataType: 'text',
        success: function(d){
            return d;
        },
        error: function(){
            console.log('no file found at localhost:2262/' + filename + '.js')
        }
    });
}

chrome.extension.onRequest.addListener(
    function(request, sender, sendResponse)
    {
        console.log("background.js received request:");
        console.log(request);
        if (request.type == "setListener")
        {
            chrome.webRequest.onBeforeRequest.addListener(request.func, request.filter);
        }
        if (request.type == "loadJS")
        {
            sendResponse(loadJSFile(request.filename));
        }
    }
);
Ben
  • 51,770
  • 36
  • 127
  • 149
Jack M
  • 4,769
  • 6
  • 43
  • 67

1 Answers1

2

There are many flaws in your code/design:

  1. Content scripts can make cross-origin AJAX request, provided that the resource URL is specified at the permissions section in the manifest file.
  2. The webRequest API does not capture any requests created within the scope of a Chrome extension.
  3. The return statement in the success handler does not return the response to the caller of loadJSFile:

        sendResponse(loadJSFile(request.filename));
    ...
    function loadJSFile(filename) {
        $.ajax({
            ...
            success: function(d){
                return d;
            } ...
    

    At least use:

    loadJSFile(request.filename, sendResponse);
    function loadJSFile(filename, sendResponse) {
        $.ajax({
            url: 'http://localhost:2262/Pigman/' + filename + '.js',
            dataType: 'text',
            success: sendResponse, /// <--- Now it works!
    

Final note on debugging: I'm pretty sure that the messages are logged in the console. You're just looking at the wrong place. See Google chrome extension - logging from background.js for the steps to read the console output for the background page.

Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks, it's gotten a lot easier now that I can see console output. I feel very lost in the world of Chrome extensions because I couldn't find any good tutorials -- and the official documentation takes a very Spartan approach. – Jack M May 01 '12 at 21:00
  • The [official documentation](http://code.google.com/chrome/extensions/devguide.html) is a decent reference. If you're in need of tips, tricks and examples, browse through [my answers in the google-chrome-extension tag](http://stackoverflow.com/search?tab=relevance&q=user%3a938089%20[google-chrome-extension]). I usually add a demo to my answers, and always include relevant references. – Rob W May 01 '12 at 21:04