“Failed to find a valid digest in the 'integrity' attribute”表示浏览器未启动SRI校验,主因是crossorigin缺失或错误、integrity格式不合法、非HTTPS/localhost协议、rel值不为stylesheet,或哈希未按线上响应体(去BOM、解压后)正确计算。

“Failed to find a valid digest in the 'integrity' attribute”不是资源没找到(404),而是浏览器压根没开始校验——它连哈希比对这一步都没走到。
为什么写了 integrity 却报 Failed to find a valid digest
这个警告出现,说明浏览器解析到 integrity 属性后,发现它不符合 SRI 校验的启动条件,于是直接跳过,不校验、不加载失败、也不报更具体的错误。常见原因包括:
-
crossorigin属性缺失、拼错(如写成crossorigin="true"或crossorigin="yes")或值不合法(crossorigin=""在 Firefox 中行为不稳定) -
integrity值格式错误:前缀大小写不对(比如SHA384-应为sha384-)、哈希部分用了 hex 编码而非 base64(sha256-abc123错,sha256-AbCdEf对) - 当前页面使用
file://协议打开,或 HTTP 协议(非 HTTPS 且非localhost),此时浏览器强制禁用 SRI,integrity被静默忽略 -
<link>的rel值不是严格等于stylesheet(比如写成sytlesheet、styleSheet、css),导致标签被浏览器忽略,连带integrity也失效
network 面板里看不到 CSS 请求?先查 rel 和协议
这个错误常和“样式完全不生效”同时出现,但根源未必是 CDN 或哈希问题。先确认基础链路是否通:
- 打开 DevTools → Elements 面板,检查
<link>标签的rel是否精确为stylesheet(注意拼写,尤其易错的sytlesheet) - 切到 Network 面板,过滤
css,刷新页面:如果目标 CSS 文件根本没出现在列表里,基本可断定是rel拼写错误或标签未闭合 - 看请求 URL 的 protocol:如果是
file://或http://(非 localhost),SRI 不生效是浏览器行为,不是配置错——必须切到https://或http://localhost才能触发校验
哈希怎么算才和浏览器一致
浏览器校验的是从线上 URL 实际返回的响应体(解压后、去 BOM、无额外空格的明文),不是你本地文件、也不是 HTML 里写的路径内容。常见偏差点:
立即学习“前端免费学习笔记(深入)”;
- CDN 启用了 Gzip/Brotli 压缩,但你用未压缩的本地文件算哈希 → 必须用
curl -sL获取线上响应,再 pipe 给openssl dgst -sha384 -binary | base64 -w0 - 服务器返回了 BOM(如 UTF-8 with BOM),而你本地文件没 BOM → 下载线上文件用
xxd或 VS Code 的 “Show All Characters” 确认 - CDN 有重定向(302),但
curl默认不跟随 → 加-L参数;否则你算的是跳转页的哈希,不是最终 CSS 的 - 算法只认
sha256、sha384、sha512;sha1已被所有主流浏览器禁用,写了也白搭
crossorigin 不配或配错,integrity 就等于没写
integrity 和 crossorigin 是绑定生效的组合,缺一不可。浏览器看到 integrity 后会强制发起 CORS 请求,但若没 crossorigin,就拿不到完整响应体,校验直接跳过:
- 通用场景一律用
crossorigin="anonymous"(最安全、兼容性最好) - 只有当资源需携带 cookies(如私有 CDN 鉴权)时,才考虑
crossorigin="use-credentials",但此时 CDN 必须返回Access-Control-Allow-Origin: *或明确域名,且不能返回Access-Control-Allow-Credentials: true与Access-Control-Allow-Origin: *共存(浏览器会拒绝) -
crossorigin属性值必须是字符串,crossorigin(无值)在部分浏览器中解析异常,不要用
真正容易被忽略的是:SRI 校验失败时,浏览器不会触发 onerror,也不会进 window.onerror,你没法靠 JS fallback。它只是静默丢弃那个 <link>,然后继续渲染——所以样式突然消失又找不到报错,大概率就是 integrity + crossorigin 这一对没配对成功,或者哈希根本没算对。



















