加了integrity却没效果的最常见原因是漏写crossorigin属性,必须同时满足integrity值正确和crossorigin存在(推荐crossorigin="anonymous"),否则浏览器静默忽略校验,样式丢失且控制台无报错。

为什么加了 integrity 却没效果?
最常见原因是漏写 crossorigin 属性。浏览器只对 CORS-enabled 请求执行 SRI 校验,而 <link rel="stylesheet"> 默认是 CORS-ineligible 请求——哪怕 integrity 值完全正确,也会被静默忽略,连 warning 都不报。样式直接丢失,页面错乱,但控制台一片空白。
必须同时满足两个条件:integrity 值正确 + crossorigin 属性存在。推荐统一用 crossorigin="anonymous"(crossorigin="" 在 Firefox 中解析不稳定);crossorigin="use-credentials" 会彻底禁用 SRI,哪怕哈希对了也无效。
怎么生成靠谱的 integrity 值?
别用本地 CSS 文件算 hash,CDN 实际返回的内容可能带 BOM、换行差异、gzip 压缩或重定向,本地文件和在线工具根本不可靠。
唯一可信方式:用命令行抓取线上真实响应体再哈希:
curl -sL https://cdn.example.com/style.css | openssl dgst -sha384 -binary | openssl base64 -A
输出结果拼成 sha384-<base64></base64> 格式。注意:-A 参数防止 base64 输出换行;SHA-384 比 SHA-256 更抗碰撞,是当前推荐算法;避免用 SHA-1 或 MD5。
- 如果 CDN 返回
Content-Encoding: gzip或br,curl -sL默认解压后计算,这恰好匹配浏览器校验逻辑(校验的是解压后字节) - 确保响应头含
Access-Control-Allow-Origin: *,否则 CORS 请求失败,SRI 无从谈起
CI/CD 中如何避免手动维护 integrity?
人工更新哈希值极易出错,尤其当构建产物 URL 含 hash 后缀(如 main.a1b2c3.css)或 query 参数(如 ?v=1.2.3)时,URL 变了但哈希没重算,SRI 形同虚设。
Webpack 用户可用 webpack-subresource-integrity 插件,它自动注入 integrity 并强制添加 crossorigin="anonymous";esbuild 或 Vite 需在构建后 hook 步骤:下载产出 CSS、计算 SHA-384、替换 HTML 中对应 <link> 标签的 integrity 和 crossorigin 属性。
SRI 失效时为什么很难发现?
浏览器不会中断渲染、不抛异常、不触发 onerror,只会静默丢弃该 CSS,并在 Console 记一条 warning 级日志:Failed to find a valid digest in the 'integrity' attribute。这条日志默认被过滤掉,极容易被忽略。
排查时优先看 Network 面板里对应请求的 Response Headers:access-control-allow-origin 是否存在、content-encoding 是否影响哈希一致性、integrity 值是否与真实响应体匹配。样式突然错乱 + 控制台“干净”,就是典型 SRI 失效信号。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











