sri校验失效的主因是未配crossorigin属性或哈希值非源自线上实际响应体;必须同时设置integrity和crossorigin="anonymous"(公开cdn)或"use-credentials"(鉴权场景),且仅script和link[rel=stylesheet]支持。

加了 integrity 却没拦住篡改脚本?大概率是校验根本没跑起来——浏览器静默跳过,不报错也不执行,页面白屏时你还在查网络请求。
为什么 integrity 属性经常“看起来生效”实则无效
浏览器只在同时满足两个硬性条件时才启动 SRI 校验:标签上存在有效的 integrity 值,且显式声明了 crossorigin 属性。缺一不可。
-
crossorigin漏写、拼错(如写成crossorigin="anonymouse")、或值不合法(如use-credentials但 CDN 没返回Access-Control-Allow-Credentials: true),都会导致校验被完全跳过 - 控制台不会提示“crossorigin 缺失”,也不会警告
integrity被忽略;你只会看到脚本没加载、样式没应用,或控制台孤零零一条Failed to find a valid digest in the 'integrity' attribute - 本地用
file://协议打开 HTML 文件时,SRI 全面禁用——哪怕所有属性都写对了,浏览器也直接无视
如何生成真正可用的 integrity 值
哈希必须基于目标 URL 实际响应体计算,不是本地文件、不是构建产物、不是在线生成器“估算”的结果。CDN 可能重定向、压缩、注入 BOM、甚至按 UA 返回不同内容,这些都会让哈希失效。
- 用这条命令最可靠:
curl -sL https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js | openssl dgst -sha384 -binary | openssl base64 -A -
-sL确保静默 + 跟随重定向,拿到浏览器最终加载的真实字节流 - 别用
sha256或sha512除非明确需要;sha384是当前兼容性与安全性平衡的最佳选择 - 多个哈希可空格分隔,例如:
integrity="sha384-xxx sha256-yyy",浏览器会逐个比对,任一匹配即通过
哪些标签支持 integrity,哪些纯属浪费时间
SRI 规范只定义了两个生效位置:<script></script> 和 <link rel="stylesheet">。其他任何地方加 integrity 都是无效操作。
-
<img src="" integrity="">、<iframe src="" integrity=""></iframe>、<link rel="icon">:浏览器完全忽略,不校验、不报错、不警告 - 动态创建的 script 标签(
document.createElement('script'))即使手动设置integrity和crossorigin,也不会触发校验 -
import()动态导入、fetch()加载的 JS 字符串、Web Worker 的new Worker(url):均不支持 SRI,需自行做内容哈希验证
常见失败现象与快速定位法
校验失败时,脚本/样式表被丢弃,且 onerror 回调不会触发——这是最容易误判的点。不能靠监听错误来确认是否拦截成功。
- 打开 DevTools → Network 标签页 → 找到对应资源 → 查看 Response Headers 是否含
access-control-allow-origin: *(或你域名) - 右键该资源 → “Open in Sources tab” → 看实际返回内容是否和你本地算哈希的文件一致(注意 BOM、换行、空格、gzip 解压后明文)
- 在 Elements 面板中检查对应
<script></script>标签,确认integrity和crossorigin是否都存在、拼写正确、值合法 - 若使用构建工具(Vite/Webpack),检查是否把 runtime chunk 或动态插入的 script 漏掉了
integrity——这些往往不在 HTML 模板里,得靠插件注入
最易被忽略的是:SRI 只管“下载下来的内容对不对”,不管“这个 URL 是谁写的”。如果 HTML 模板本身被 XSS 注入、服务端模板被污染、或构建产物被篡改,integrity 值可能早就是错的——它防不住源头被攻破,只防传输链路被劫持。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











