Tammy
Tammy

Reputation: 1132

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

I am getting DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules . Any suggestion how can I resolve the same.

Sample-Code

function copyStyles(source, target) {
  Array.from(source.styleSheets).forEach(styleSheet => {
    let rules
    try {
      rules = styleSheet.cssRules
    } catch (err) {
      console.error(err)
    }
    if (rules) {
      const newStyleEl = source.createElement('style')

      Array.from(styleSheet.cssRules).forEach(cssRule => {
        .......
        
      })
      target.head.appendChild(newStyleEl)
    } else if (styleSheet.href) {
      ..........
    }
  })
}

Upvotes: 0

Views: 4307

Answers (2)

panghal0
panghal0

Reputation: 551

As per the CORS security policy, you can not access the contents of resources loaded from a third-party domain via javascript. This applies to CSS files as well (though not implemented by all browsers yet).

So if one of the source.styleSheets is a third-party CSS file, then you will receive this error while trying to access the cssRules or rules properties of the stylesheet

By the way as a solution to what you are trying, instead of creating link tags in the else part, fetch (via xhr or fetch API) the stylesheet.href and you will have the response in the JS as text which can be appended to a style tag in DOM.

Example

fetch(stylesheet.href)
  .then(response => response.text())
  .then(response => {
      const st = document.createElement('style');
      st.textContent = response;
      document.body.append(st);
  });

Upvotes: 2

WebUser
WebUser

Reputation: 7

I suggest you avoid calling cssRules that may be protected via CSP, and instead just add a new stylesheet with whatever rules you want that override the existing ones.

Like this...

var S=document.createElement('style');

S.innerHTML='#Menu{background:red;} body{overflow:auto;}';

Frame_ID.contentWindow.document.body.appendChild(S);

Upvotes: 1

Related Questions