未捕获的 DOMException:无法从 'CSSStyleSheet' 读取 'rules' 属性
Uncaught DOMException: Failed to read the 'rules' property from 'CSSStyleSheet'
在 Code.org 的应用实验室编辑器中,我们最近开始在 Chrome 64 中看到此错误:
Uncaught DOMException: Failed to read the 'rules' property from 'CSSStyleSheet'
此函数引发错误,旨在检测浏览器是否正在使用 CSS 媒体查询,在包含 styleSheets[i].cssRules
.
的行上
/**
* IE9 throws an exception when trying to access the media field of a stylesheet
*/
export function browserSupportsCssMedia() {
var styleSheets = document.styleSheets;
for (var i = 0; i < styleSheets.length; i++) {
var rules = styleSheets[i].cssRules || styleSheets[i].rules;
try {
if (rules.length > 0) {
// see if we can access media
rules[0].media;
}
} catch (e) {
return false;
}
}
return true;
}
问题已在 Windows、OSX、Ubuntu 和 ChromeOS 上发现;在 Chrome 版本 64.0.3282.167 和 64.0.3282.186 上。但是,我们也看到这个问题 not 发生在完全相同的 Chrome 版本和平台上 - 我们似乎无法在隐身模式下重现该问题window.
此错误的根本原因是什么?
这是一个很好的故事,对 Web 开发人员来说是一个新的 'gotcha',所以我不得不分享:
Chrome 64.0.3282.0(2018 年 1 月发布,full change list)对样式表的安全规则进行了更改。我很恼火,因为我在任何不如完整提交列表详细的更新日志中找不到此更改。
在 Chromium 中提交 a4ebe08 描述:
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()
此提交修复了错误 Security: Inconsistent CORS implementation regarding CSS and the link element. 链接的 W3C 规范详细描述了使用 CSS 对象模型需要 same-origin 访问权限的地方。
综上所述,为什么这个问题会出现在 App Lab 中?我们不应该遇到任何 CORS 问题,因为我们只从我们自己的来源加载样式表:
最后的线索是我们无法在私人选项卡中重现此问题。我们开始查看 Chrome 扩展并意识到一些受影响的用户启用了 Loom Video Recorder 扩展,这似乎将其自己的 CSS 注入到页面中。由于我们的(原始)函数正在遍历 所有 加载的样式表,它试图访问由扩展注入的样式表,从而导致 CORS 错误。
也就是说,在 Chrome 中仍然存在一些悬而未决的问题和关于这一变化的争论:
- This comment 在最初的安全漏洞上抱怨说,现在检测样式表无法从 JavaScript 访问的唯一方法是使用
try/catch
.
- 1 月 23 日发现的 Chromium 错误 (document.styleSheets.cssRules is null even with Access-Control-Allow-Origin: *) 表明新安全规则可能存在实施问题,破坏了某些解决方法。
- 正在实施的规范看起来相当稳定,但它仍然具有 "Working Draft" 状态,所以谁知道它会落在哪里以及其他浏览器将实施什么。
To fix our problem, we just tore out the entire function. 我们不再支持 IE9,我们知道我们支持的所有浏览器都能正确处理媒体查询。
相关(但不完全重复)问题:
如果其他人遇到与跨源资源共享 (CORS) 政策相关的问题,请在此处讨论:https://github.com/Modernizr/Modernizr/issues/2296
您将必须使用本地主机进行测试:
https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server
这里是解决方法 "try/catch" 方法:
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
}
遇到这个问题并且绞尽脑汁,这似乎有效...祝你好运!
对我来说,将 css link href 从 header 移动到 body 标签结尾。
<link rel="stylesheet" href=".....">
</body>
在 Code.org 的应用实验室编辑器中,我们最近开始在 Chrome 64 中看到此错误:
Uncaught DOMException: Failed to read the 'rules' property from 'CSSStyleSheet'
此函数引发错误,旨在检测浏览器是否正在使用 CSS 媒体查询,在包含 styleSheets[i].cssRules
.
/**
* IE9 throws an exception when trying to access the media field of a stylesheet
*/
export function browserSupportsCssMedia() {
var styleSheets = document.styleSheets;
for (var i = 0; i < styleSheets.length; i++) {
var rules = styleSheets[i].cssRules || styleSheets[i].rules;
try {
if (rules.length > 0) {
// see if we can access media
rules[0].media;
}
} catch (e) {
return false;
}
}
return true;
}
问题已在 Windows、OSX、Ubuntu 和 ChromeOS 上发现;在 Chrome 版本 64.0.3282.167 和 64.0.3282.186 上。但是,我们也看到这个问题 not 发生在完全相同的 Chrome 版本和平台上 - 我们似乎无法在隐身模式下重现该问题window.
此错误的根本原因是什么?
这是一个很好的故事,对 Web 开发人员来说是一个新的 'gotcha',所以我不得不分享:
Chrome 64.0.3282.0(2018 年 1 月发布,full change list)对样式表的安全规则进行了更改。我很恼火,因为我在任何不如完整提交列表详细的更新日志中找不到此更改。
在 Chromium 中提交 a4ebe08 描述:
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()
此提交修复了错误 Security: Inconsistent CORS implementation regarding CSS and the link element. 链接的 W3C 规范详细描述了使用 CSS 对象模型需要 same-origin 访问权限的地方。
综上所述,为什么这个问题会出现在 App Lab 中?我们不应该遇到任何 CORS 问题,因为我们只从我们自己的来源加载样式表:
最后的线索是我们无法在私人选项卡中重现此问题。我们开始查看 Chrome 扩展并意识到一些受影响的用户启用了 Loom Video Recorder 扩展,这似乎将其自己的 CSS 注入到页面中。由于我们的(原始)函数正在遍历 所有 加载的样式表,它试图访问由扩展注入的样式表,从而导致 CORS 错误。
也就是说,在 Chrome 中仍然存在一些悬而未决的问题和关于这一变化的争论:
- This comment 在最初的安全漏洞上抱怨说,现在检测样式表无法从 JavaScript 访问的唯一方法是使用
try/catch
. - 1 月 23 日发现的 Chromium 错误 (document.styleSheets.cssRules is null even with Access-Control-Allow-Origin: *) 表明新安全规则可能存在实施问题,破坏了某些解决方法。
- 正在实施的规范看起来相当稳定,但它仍然具有 "Working Draft" 状态,所以谁知道它会落在哪里以及其他浏览器将实施什么。
To fix our problem, we just tore out the entire function. 我们不再支持 IE9,我们知道我们支持的所有浏览器都能正确处理媒体查询。
相关(但不完全重复)问题:
如果其他人遇到与跨源资源共享 (CORS) 政策相关的问题,请在此处讨论:https://github.com/Modernizr/Modernizr/issues/2296
您将必须使用本地主机进行测试: https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server
这里是解决方法 "try/catch" 方法:
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
}
遇到这个问题并且绞尽脑汁,这似乎有效...祝你好运!
对我来说,将 css link href 从 header 移动到 body 标签结尾。
<link rel="stylesheet" href=".....">
</body>