SRI校验需同时配置integrity和crossorigin属性,缺一不可;哈希值须基于CDN实际响应体计算,仅script和link[rel=stylesheet]支持。

加了 integrity 却没生效?八成是漏了 crossorigin="anonymous",或者哈希值根本不是从 CDN 实际响应体算出来的。
为什么 script 标签加了 integrity 却没校验?
浏览器对 integrity 的校验有硬性前提:必须配合 crossorigin 属性,且值为 "anonymous" 或 "use-credentials"。不写、写错(比如 crossorigin="true")、或服务端没返回 Access-Control-Allow-Origin 头,integrity 就会被静默忽略——既不报错,也不拦资源。
常见错误现象包括:
-
Failed to find a valid digest in the 'integrity' attribute(控制台报这个错,说明浏览器尝试校验但没找到合法哈希格式) - 页面白屏、功能缺失,但 Network 面板里脚本状态是 200,控制台却无其他报错(其实是 SRI 拦住了,但你没看到 error 事件)
- 本地开发时一切正常,上线后 JS/CSS 不加载(CDN 响应头缺失 CORS,或用了不支持的镜像站)
如何生成真正可用的 integrity 值?
不能靠本地文件、不能信在线生成器、不能抄别人页面里的值。CDN 可能按 UA、Accept-Encoding(gzip/Brotli)、甚至重定向返回不同内容,哈希必须基于真实 HTTP 响应体计算。
立即学习“前端免费学习笔记(深入)”;
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
最可靠的做法是用命令行直接请求 CDN URL,拿到解压后的原始字节再哈希:
curl -sL https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js | openssl dgst -sha384 -binary | openssl base64 -A
注意点:
- 必须加
-sL:静默 + 跟重定向,否则可能哈希的是 302 响应体 - 不用解压参数(如
--compressed):curl默认自动处理 gzip/Brotli,返回的是浏览器实际收到的解压后字节 - BOM、换行符、末尾空格都会导致哈希不一致,构建流程中 minify 工具差异要统一
- 算法只支持
sha256、sha384、sha512,前缀必须小写,例如sha384-,不能写成SHA384-
CDN 不支持 CORS 怎么办?
如果目标 CDN(比如某些老旧镜像或内网私有 CDN)不返回 Access-Control-Allow-Origin: *,加了 crossorigin 会导致请求失败,资源彻底加载不了。
这时得权衡:
- 换用 jsDelivr、unpkg、cdnjs 等主流 CDN,它们都默认返回
Access-Control-Allow-Origin: * - 自己搭代理层,加 CORS 头再转发请求(适合私有资源)
- 放弃 SRI,改用服务端指纹备案 + 定期巡检(适用于高敏场景,但已超出
integrity能力范围)
别把 integrity 当银弹——它只校验传输完整性,不防版本误用、不防 CDN 本身被攻陷、也不防服务端返回恶意内容。真要防供应链攻击,得锁死版本号、轮换哈希、搭配私有 CDN 和服务端指纹核验。


















