Chrome extension – retrieving global variable from webpage

Content scripts run in an isolated environment. To get access to the any global properties (of the page’s window), you have to either inject a new <script> element, or use event listeners for passing data.

See this answer for example on injecting a <script> element in the context of the page.

Example

contentscript.js ("run_at": "document_end" in manifest):

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

// Event listener
document.addEventListener('RW759_connectExtension', function(e) {
    // e.detail contains the transferred data (can be anything, ranging
    // from JavaScript objects to strings).
    // Do something, for example:
    alert(e.detail);
});

script.js – Located in the extension directory, this will be injected into the page itself:

setTimeout(function() {
    /* Example: Send data from the page to your Chrome extension */
    document.dispatchEvent(new CustomEvent('RW759_connectExtension', {
        detail: GLOBALS // Some variable from Gmail.
    }));
}, 0);

Since this file is being loaded via a chrome-extension: URL from within the DOM, “script.js” must be added to the web_accessible_resources section of the manifest file. Otherwise Chrome will refuse to load the script file.

You should run as little logic as possible in the web page, and handle most of your logic in the content script. This has multiple reasons. First and foremost, any script injected in the page runs in the same context as the web page, so the web page can (deliberately or inadvertently) modify JavaScript/DOM methods in such a way that your extension stops working. Secondly, content script have access to extra features, such a limited subset of the chrome.* APIs and cross-origin network requests (provided that the extension has declared permissions for those).

Leave a Comment