Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access cssRules from local css file in Chrome 64

Tags:

Here's a simple example of the problem:

<html> <head> <link rel='stylesheet' href='myStyle.css'> <script> window.onload=function(){     try{         alert(document.styleSheets[0]); // works         alert(document.styleSheets[0].cssRules); // doesn't even print undefined     }catch(e){alert(e);} // catch and alert the error } </script> </head> <body> </body> </html> 

myStyle.css body{background-color:green;}

The script works fine with <style></style>

Solutions:

  1. Works when files are online/localhost.
  2. Works with other browsers. (i.e. Internet Explorer, Microsoft Edge, Firefox)
  3. chrome --allow-file-access-from-files
like image 386
Puddle Avatar asked Feb 12 '18 19:02

Puddle


1 Answers

TL;DR: As of Chrome 64 you'll need to use a local development server to test functionality that depends on the CSS Object Model.

Accessing CSS rules in a stylesheet loaded from the local filesystem violates a Cross-Origin Resource Sharing (CORS) policy - but Chrome didn't enforce this until recently, and other browsers don't seem to enforce it yet.

Chrome 64.0.3282.0 (released January 2018, full change list) includes a change to security rules for stylesheets. 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.

This is a real security constraint and the solution you posted (online/localhost) is probably the most typical workaround. For more information check out MDN's How do you set up a local testing server? - it discusses why and how to use a local development server to avoid CORS issues.

That said, there's still some open issues and debate around this change.

  • 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.
like image 169
Brad Buchanan Avatar answered Sep 22 '22 01:09

Brad Buchanan