Max Zhuravlev
Max Zhuravlev

Reputation: 334

chrome.tabs.executeScript: How to get access to variable from content script in background script?

How to get access to variable app from content script app.js in background script background.js?

Here is how I try it (background.js):

chrome.tabs.executeScript(null, { file: "app.js" }, function() {
   app.getSettings('authorizeInProgress'); //...
});

Here is what I get: Error during tabs.executeScript: Cannot access contents of url "chrome-devtools://devtools/devtools.html?docked=true&dockSide=bottom&toolbarColor=rgba(223,223,223,1)&textColor=rgba(0,0,0,1)". Extension manifest must request permission to access this host. \n Uncaught ReferenceError: app is not defined

Here is manifest.json:

{
  "name": "ctrl-vk",
  "version": "0.1.3",
  "manifest_version": 2,
  "description": "Chrome extension for ctrl+v insertion of images to vk.com",

  "content_scripts": [{
    "matches": [
        "http://*/*",
        "https://*/*"
    ],
    "js": ["jquery-1.9.1.min.js"
    ],
    "run_at": "document_end"
  }],

  "web_accessible_resources": [
    "jquery-1.9.1.min.js"
  ],

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

  "background": {
    "persistent": false,
    "scripts": ["background.js"]
  }
}

Full code for instance, at github

https://github.com/MaxLord/ctrl-vk/tree/with_bug

Upvotes: 7

Views: 6135

Answers (3)

stt
stt

Reputation: 342

(Would've submitted this as comment to the accepted answer but still lack the required reputation)

You should also give the tabId to chrome.tabs.executeScript as first argument when you have it. Otherwise you risk user switching windows/tabs right after requesting a URL and background.js doing executeScript against wrong page.

While fairly obvious on hindsight it threw me for a loop when I got that same error message "Cannot access contents of url "chrome-devtools://.." even though my chrome.tabs.onUpdated eventhandler was checking that the page user requested had some specific domain name just before doing the executeScript call.

So keep in mind, chrome.tabs.executeScript(null,..) runs the script in active window, even if the active window might be developer tools inspector.

Upvotes: 1

Franky Yang
Franky Yang

Reputation: 221

We should notice that, in the manifest cofig:

"content_scripts": [{
"matches": [
    "http://*/*",
    "https://*/*"
],
"js": ["jquery-1.9.1.min.js"
],

in the "matches" part, only http, https are matched, so if you load your extension in page like: 'chrome://extensions/', or 'file:///D:xxx', that error will occur.

You may load your extension in the page with the url 'http://'; or add more rules in your 'matches' array.

Upvotes: 0

Sudarshan
Sudarshan

Reputation: 18534

To avoid above error use following code

if (tab.url.indexOf("chrome-devtools://") == -1) {
    chrome.tabs.executeScript(tabId, {
        file: "app.js"
    }, function () {

        if (app.getSettings('authorizeInProgress')) {
            alert('my tab');
            REDIRECT_URI = app.getSettings('REDIRECT_URI');
            if (tab.url.indexOf(REDIRECT_URI + "#access_token") >= 0) {
                app.setSettings('authorize_in_progress', false);
                chrome.tabs.remove(tabId);
                return app.finishAuthorize(tab.url);
            }
        } else {
            alert('not my');
        }

    });
}

instead of

chrome.tabs.executeScript(null, {
    file: "app.js"
}, function () {

    if (app.getSettings('authorizeInProgress')) {
        alert('my tab');
        REDIRECT_URI = app.getSettings('REDIRECT_URI');
        if (tab.url.indexOf(REDIRECT_URI + "#access_token") >= 0) {
            app.setSettings('authorize_in_progress', false);
            chrome.tabs.remove(tabId);
            return app.finishAuthorize(tab.url);
        }
    } else {
        alert('not my');
    }

});

Explanation

  • chrome://extensions/ page also fires chrome.tabs.onUpdated event, to avoid it we have to add a filter to skip all dev-tool pages.

Upvotes: 2

Related Questions