IvanSpk
IvanSpk

Reputation: 137

Get css rules, chrome extension

I am working on Chrome extension, which need to get access to document.styleSheets cssRules. It works fine with some websites, e.g. w3school, but others don't, like stackoverflow. I am getting an error:

Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules

I know about CORS policy for Chrome browser but I am embeding script into the page using this approach:

chrome.tabs.executeScript(tabId, {file:'script.js'});

Seems to me the problem is caused because file with styles are downloaded from other domain, but for me isn't clear why I am getting the error, the script is embedded on the page and code executes in scope of website. Could you please clarify, what is the problem?

Stuff with chrome.debugger also not works:

chrome.debugger.attach(debuggeeId, "1.3", () => {
    chrome.debugger.sendCommand(debuggeeId, "Page.enable", null, (r) => {
        chrome.debugger.sendCommand(debuggeeId, "Page.getResourceTree", null, (res) => {
            const cssResources = getCSSResources(res.frameTree.resources);
            for(let url of cssResources) {
                chrome.debugger.sendCommand(debuggeeId, "Page.getResourceContent", {frameId: toString(tabId), url: url}, (resp) => {
                    console.log(resp)
                })
            }
        })
    })
})

Upvotes: 2

Views: 579

Answers (1)

woxxom
woxxom

Reputation: 73726

Content script of an extension obeys the same cross-origin rules as the page where it runs and just like the page it cannot read cross-origin style sheets. This is by design.

The only reliable method is to use chrome.debugger API with Page.getResourceTree command to get the entire list of loaded resources then use Page.getResourceContent on each returned resource URL to get its actual contents exactly as it was loaded on the page without making a new network request.

The slightly less reliable approach is to use a content script to read entries from document.styleSheets: those that succeed will be same-origin, those that fail will be cross-origin so you can accumulate a list of their URLs and tell the background script to fetch them (the permissions in manifest.json must allow those URLs, for example "*://*/").

Upvotes: 3

Related Questions