integrity校验失败时浏览器直接丢弃CSS资源,不解析不执行;必须同时设置integrity和crossorigin="anonymous",缺一则静默跳过校验,且仅<link rel="stylesheet">和<script>生效。

integrity校验失败时浏览器根本不会加载CSS文件
写了 integrity 却没配 crossorigin,浏览器会静默跳过校验,资源照常加载;但一旦校验失败,浏览器直接丢弃响应体,不解析、不执行、不触发 onerror,页面就变成纯 HTML 流式布局——你看到的“样式加载不出来”,其实是 CSS 根本没进样式引擎。
控制台只会报一句模糊警告:Failed to find a valid digest in the 'integrity' attribute 或 The resource <url> was blocked because integrity check failed</url>,不会提示缺 crossorigin,也不会显示网络请求失败。
- 必须同时存在
integrity和crossorigin="anonymous",缺一不可 -
crossorigin=""在 Firefox 中行为不稳定,统一用crossorigin="anonymous" - CDN 返回的响应头必须含
Access-Control-Allow-Origin: *(或具体域名),否则 CORS 请求直接失败 - 如果用了
crossorigin="use-credentials",后端还必须返回Access-Control-Allow-Credentials: true且Access-Control-Allow-Origin不能是*
哈希值不是本地文件算的,得用线上真实响应体
你本地用 openssl dgst -sha384 -binary style.css | base64 -w0 算出来的哈希,大概率和浏览器校验的不一致——因为 CDN 可能做了 Gzip 压缩、BOM 插入、重定向、甚至根据 UA 返回不同版本。
正确做法是模拟浏览器请求流程,拿到解压后的明文再算哈希:
立即学习“前端免费学习笔记(深入)”;
- 用
curl -sL https://cdn.example.com/style.css跟随重定向并静默输出 - 管道进
openssl dgst -sha384 -binary,再base64 -w0 - 算法优先选
sha384:比sha256抗碰撞更强,主流 CDN 都支持 - 哈希值必须是 Base64 编码字符串,不能是 hex(比如
sha256-abc123是错的,sha384-AbCdEf...才对)
哪些地方加了integrity也白搭
integrity 是 W3C 明确定义的机制,只对两类标签生效:<script> 和 <link rel="stylesheet">。其他所有情况浏览器直接忽略,不报错也不校验。
-
<link rel="icon">、<link rel="preload">、<img integrity="">:写了等于没写 -
<link rel="stylesheet" href="..." integrity="...">但rel拼错成sytlesheet:浏览器根本不识别该标签,连请求都不发 - 用
document.createElement('link')动态插入:浏览器不校验,只认 HTML 解析阶段的静态标签 - 内联
<style>或<script>:integrity属性无效
校验失败后怎么 fallback
浏览器丢弃资源后不会触发 onerror,但会派发全局 error 事件,你可以捕获并加载备用资源:
document.addEventListener('error', e => {
if (e.target.matches('link[rel=stylesheet]')) {
const fallback = document.createElement('link');
fallback.rel = 'stylesheet';
fallback.href = '/css/style.fallback.css';
document.head.appendChild(fallback);
}
});
注意这个监听要放在 <head> 最前面,越早注册越可能捕获到事件;另外,fallback.css 自身不能再带 integrity,否则又陷入同样问题。
真正容易被忽略的是:CDN 响应体是否被压缩、重定向是否被跟踪、以及 crossorigin 是否漏写——这三者任一出问题,integrity 就形同虚设,而浏览器不会给你任何明确线索。



















