integrity属性不生效的最常见原因是未与crossorigin="anonymous"成对使用,因CSS默认以no-cors模式加载,此时integrity被浏览器静默忽略,既不校验也不报错。

integrity 属性不生效的最常见原因
单独写 integrity 属性,浏览器直接忽略——它必须和 crossorigin="anonymous" 成对出现才触发校验。这是绝大多数人第一次配就失败的核心原因。CSS 默认以 no-cors 模式加载,此时 integrity 完全被无视,连控制台都不会报错,只会静默降级加载。
常见错误现象包括:
- 页面样式突然错乱,但控制台没报
Failed to find a valid digest - 明明写了
integrity,Lighthouse 仍标红 “Missing Subresource Integrity” - 换了个 CDN 域名,哈希值照搬过去,结果失效(哈希与域名无关,但与文件字节强绑定)
生成合法 integrity 值的关键约束
哈希不是对“你看到的 CSS 文件”算的,而是对最终上线、未压缩、无 BOM、UTF-8 编码的原始字节内容计算。任何构建步骤(Terser 压缩、PostCSS 处理、BOM 插入、换行符标准化)都会改变哈希结果。
推荐做法:
立即学习“前端免费学习笔记(深入)”;
- 在构建产物生成后、上传 CDN 前,用本地命令行算哈希:
openssl dgst -sha384 -binary style.css | base64 -A - 避免使用在线生成器——你无法验证它是否去除了 BOM 或统一了行尾符
- 若 CSS 含环境变量(如
env.BASE_URL),确保构建时已稳定替换,否则每次哈希都不同 - 不要复制别人页面里扒下来的
integrity值,哪怕 URL 完全一样
CDN 资源必须加 crossorigin="anonymous"
crossorigin="anonymous" 不代表“跨域才需要”,它强制浏览器发起一个带 Origin 请求头的 CORS 请求,从而让 integrity 校验逻辑启用。即使资源同源(比如你自己托管在 https://cdn.yoursite.com),也必须加。
注意点:
- 服务端需返回
Access-Control-Allow-Origin: *(或具体域名),否则资源会被标记为“污染”,后续无法用于 canvas 等敏感 API -
crossorigin="use-credentials"也可启用校验,但会携带 cookie,一般不用于公开 CSS - HTTP/2 下无额外预检开销;HTTP/1.1 中会多一次 OPTIONS 预检,但远小于被篡改的风险成本
实际使用的完整写法与易错点
正确示例:<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-..." crossorigin="anonymous">
关键细节:
-
integrity值必须是sha256-、sha384-或sha512-开头,后接 Base64 编码字符串,不能是 hex 字符串 - 多个哈希可用空格分隔,浏览器从左到右匹配,只采用首个成功项
- 如果服务端启用了 Brotli 压缩,没问题——SRI 校验的是原始未压缩字节,不是响应体
- 若控制台报
Failed to find a valid digest,优先检查:是否漏了crossorigin、哈希是否基于构建后产物、文件编码是否为 UTF-8 无 BOM
真正难的不是算哈希,而是确保整个交付链路字节确定:构建产物、部署过程、CDN 缓存策略,三者缺一不可。一旦其中某环引入非确定性(比如时间戳注入、hash 命名未锁定),SRI 就会变成定时炸弹。


















