2

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)
                })
            }
        })
    })
})
IvanSpk
  • 137
  • 1
  • 12

1 Answers1

2

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 "*://*/").

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • But it only returns info about resources. What should I do with this info? – IvanSpk Sep 08 '20 at 12:29
  • Ah, use [Page.getResourceContent](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-getResourceContent) on each returned info. – wOxxOm Sep 08 '20 at 13:37
  • Still no success, added code sample to the question – IvanSpk Sep 08 '20 at 17:33
  • My answer is a pointer to the solution, not the solution itself. You can ask a new question with a proper [MCVE](/help/mcve), not just a fragment of code. At this point I don't know what happens there and I'm not even sure you're opening the [correct devtools console](https://stackoverflow.com/a/38920982). – wOxxOm Sep 08 '20 at 18:20
  • I want to modify CSS rules in my chrome extension. I don't need to fetch the file contents. What a bummer. I could have added css rules to the page that would override these, but for some reason there is no way to unset scrollbar css https://stackoverflow.com/questions/9060421/css3-how-to-restore-webkit-scrollbar-property-to-the-default-scroll-bar#comment116433260_9060446 – ubershmekel May 10 '21 at 06:42