Failed to find a valid digest in the 'integrity' attribute 表明SRI校验启动失败,而非CDN被劫持;根本原因是integrity值前缀错误(如SHA384-)、哈希非base64编码、crossorigin缺失或非法、或CDN未返回Access-Control-Allow-Origin:*导致CORS请求失败。

加了 integrity 属性,CDN 解析报错(比如白屏、TypeError: xxx is not a function)时,它大概率根本没起作用——不是防不住,是压根没校验。
Failed to find a valid digest in the 'integrity' attribute 是什么信号
这不是 CDN 被劫持的证据,而是 SRI 校验流程“启动失败”的明确提示。浏览器尝试读取 integrity 值,但解析出错,于是直接跳过整个校验逻辑,资源照常加载(可能已被篡改,也可能只是配置错了)。
常见原因包括:
-
integrity值写错前缀,比如SHA384-xxx(必须小写sha384-)或sha384:xxx(冒号无效) - 哈希值用了 hex 编码而非 base64(如
sha256-abc123错,sha256-AbCdEf对) -
crossorigin属性缺失、拼错(如crossorigin="true")、或值非法(如空字符串) - CDN 响应头没返回
Access-Control-Allow-Origin: *,导致 CORS 请求失败,浏览器拿不到响应体来比对
为什么 crossorigin="anonymous" 不能省
因为 integrity 校验强制走 CORS 流程。没有 crossorigin,浏览器连响应体都读不到,自然无法计算哈希——这不是 bug,是规范设计。
立即学习“前端免费学习笔记(深入)”;
关键点:
- 公开 CDN(jsDelivr、unpkg、cdnjs)全部支持
crossorigin="anonymous",这是唯一推荐值 -
crossorigin="use-credentials"极少用,且要求服务端同步返回Access-Control-Allow-Credentials: true和明确域名的Access-Control-Allow-Origin,否则请求直接失败 - 即使脚本同源(比如你自己的 CDN),也必须显式写
crossorigin="anonymous",否则不校验
怎么生成一个不会翻车的 integrity 值
别信本地文件、别抄别人页面、别依赖在线工具。唯一可靠方式是命令行直取 CDN 实际响应体:
curl -sL https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.global.js | openssl dgst -sha384 -binary | openssl base64 -A
注意:
-
-sL必须:静默 + 跟重定向,否则哈希的是 302 响应体 - 不用手动解压:
curl默认自动处理 gzip/Brotli,返回的就是浏览器实际收到的解压后字节 - BOM、末尾换行、空格都会破坏哈希,确保 CDN 返回的是干净 UTF-8 无 BOM 内容
- 优先用
sha384-:抗碰撞更强,Chrome/Firefox/Edge 全支持;sha512-在部分浏览器中被忽略
真正难防的不是劫持,是哈希漂移
上线后脚本突然失效,往往不是 CDN 被黑,而是构建流程或 CDN 策略导致字节流变了:Node.js 版本差异让 base64 编码微偏、Babel 插件插入了 sourcemap 注释、CDN 自动加了 BOM、甚至压缩工具版本升级改变了空格处理逻辑……这些都会让哈希不匹配,而浏览器只报一句轻描淡写的 warning,很容易被忽略。



















