SRI(子资源完整性)需手动添加integrity属性,浏览器仅当该属性存在且格式正确时才校验资源哈希;crossorigin属性必须同时设置以支持跨域响应体读取,二者缺一不可。

什么是SRI,为什么必须手动加integrity属性
SRI(Subresource Integrity)不是自动生效的机制,浏览器只在校验脚本或样式表的integrity属性存在且格式正确时才执行哈希比对。没写这个属性,哪怕CDN返回了正确资源,也完全不校验——这和CSP的require-sri-for策略无关,后者只是强制要求必须提供integrity,但不会帮你生成它。
常见错误是以为加了crossorigin就等于启用了SRI,其实crossorigin只是让跨域请求能读取响应体以供校验,没有integrity,校验根本不会触发。
-
integrity值必须是标准格式:sha256-xxx、sha384-xxx或sha512-xxx,不能省略前缀,也不能用base64以外的编码 - 哈希必须基于资源原始字节计算,不是文件内容字符串再UTF-8编码后的结果(比如某些在线工具误把JSON字符串当原始字节处理)
- 同一份JS,如果通过不同CDN加载(如unpkg vs jsDelivr),哈希值通常不同,因为响应头、压缩方式或BOM可能影响字节流
怎么生成合法的integrity值
最可靠的方式是下载目标资源到本地,用命令行工具计算。Node.js用户可用openssl,前端开发者可直接用浏览器控制台临时生成:
curl -s https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.global.js | openssl dgst -sha384 -binary | openssl base64 -A
输出类似sha384-o7QF...=,直接复制进integrity属性即可。注意:不要用在线SRI生成器,它们常因HTTP重定向、gzip压缩或CDN缓存导致字节不一致。
立即学习“前端免费学习笔记(深入)”;
- 务必确认下载的URL与HTML中
src完全一致(含协议、路径、查询参数) - 若资源带
?v=1.2.3这类版本参数,哈希必须基于带参数的完整URL响应内容生成 - 使用
sha256足够安全,sha384兼容性更好(IE不支持sha512)
<script>标签里crossorigin和integrity必须同时出现
缺一不可。只写integrity会导致浏览器忽略校验(报错Failed to find a valid digest in the 'integrity' attribute);只写crossorigin则无校验行为,且可能因CORS策略失败而阻塞加载。
正确写法:
<script src="https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.global.js"
integrity="sha384-o7QF..."
crossorigin="anonymous"></script>
-
crossorigin="anonymous"是推荐值,避免发送Cookie;设为"use-credentials"需服务端明确允许凭据 - 如果CDN不支持CORS(如某些老旧静态托管),
crossorigin会导致请求失败,此时SRI无法启用 - 动态插入的
<script>(如通过document.createElement)同样需要手动设置这两个属性,否则不校验
遇到Integrity check failed该怎么排查
错误信息通常出现在浏览器控制台,核心原因永远是「本地计算的哈希」≠「实际加载资源的字节哈希」。不是算法选错,而是输入源不对。
- 检查是否用了压缩版(.min.js)却按未压缩版(.js)生成哈希
- 确认CDN是否对资源做了动态修改(如自动注入分析代码、添加sourceMap注释)
- 用
curl -I看响应头是否有Content-Encoding: gzip,若有,需解压后再算哈希(curl -s URL | gunzip | openssl ...) - Chrome开发者工具Network面板中右键资源 → “Save as…”保存后重新计算,这是最准的验证方式
真正麻烦的点在于:SRI失败时脚本静默不执行,页面可能白屏或功能缺失,但控制台错误容易被忽略——尤其在CI/CD流程里没做资源哈希自动化校验时。



















