Uncaught DOMException: Failed to read the 'rules' property from 'CSSStyleSheet'

有些话、适合烂在心里 提交于 2019-11-30 23:19:08

This was a good story and a new 'gotcha' for web developers, so I just had to share:

Chrome 64.0.3282.0 (released January 2018, full change list) introduced a change to security rules for stylesheets. I'm irritated that I couldn't find this change in any changelog less detailed than the full commit list.

Commit a4ebe08 in Chromium is described:

Update behavior of CSSStyleSheet to match spec for Security origin

Spec is here: https://www.w3.org/TR/cssom-1/#the-cssstylesheet-interface

Updated: the following methods now throw a SecurityError if the style sheet is not accessible:

  • cssRules() / rules()
  • insertRule()
  • deleteRule()

This commit is a fix for the bug Security: Inconsistent CORS implementation regarding CSS and the link element. The linked W3C spec describes in detail where use of the CSS Object Model requires same-origin access.

All that said, why was this issue showing up in App Lab? We shouldn't experience any CORS issues, because we only load stylesheets from our own origin:

The final clue was that we couldn't reproduce this issue in a private tab. We started looking at Chrome extensions and realized that some affected users had the Loom Video Recorder extension enabled, which seems to inject its own CSS into the page. Since our (naïve) function was iterating through all loaded stylesheets, it was attempting to access this stylesheet injected by the extension and thus causing the CORS error.

That said, there's still some open issues and debate around this change in Chrome:

  • This comment on the original security bug complains that the only way now to detect that the stylesheet is not accessible from JavaScript is with a try/catch.
  • A Chromium bug opened January 23rd (document.styleSheets.cssRules is null even with Access-Control-Allow-Origin: *) suggests there may be an implementation issue with the new security rule that breaks certain workarounds.
  • The spec being implemented seems pretty stable, but it still has "Working Draft" status so who knows where it will land and what other browsers will implement.

To fix our problem, we just tore out the entire function. We don't support IE9 anymore, and we know all of our supported browsers handle media queries properly.

Related (but not quite duplicate) questions:

In case anyone else has this issue related to the Cross-Origin Resource Sharing (CORS) policy it is discussed here: https://github.com/Modernizr/Modernizr/issues/2296

You will have to test using a local host: https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server

Here is the workaround a "try/catch" method:

try {
  var classes = stylesheets[s].rules || stylesheets[s].cssRules;
} catch (e) {
  console.warn("Can't read the css rules of: " + stylesheets[s].href, e);
  continue
}

Had this issue and was racking my brain and this seemed to work...Good luck!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!