必须同时设置integrity和crossorigin="anonymous"属性,且integrity值须基于线上真实响应体计算,否则css不加载。

为什么只加 integrity 属性 CSS 就不加载了
浏览器根本不会校验——integrity 单独存在时完全无效。SRI 校验只在 CORS 请求流程中触发,而 <link rel="stylesheet"> 默认是 CORS-ineligible 请求。漏写 crossorigin,哪怕 integrity 值完全正确,也会被静默忽略,样式直接丢失,控制台只有一条容易被过滤掉的 warning:Failed to find a valid digest in the 'integrity' attribute。
必须同时满足两个条件:
-
integrity值格式正确(如sha384-xxx),且基于线上真实响应体计算 -
crossorigin属性显式存在,值推荐为"anonymous"(crossorigin=""在 Firefox 中解析不稳定;crossorigin="use-credentials"会禁用 SRI)
如何生成真正可用的 integrity 值
本地文件、在线生成器、甚至构建产物里抄的哈希,99% 不匹配。CDN 可能返回 gzip/Brotli 压缩内容、重定向、BOM、换行差异,甚至按 UA 返回不同版本。唯一可信方式是抓取线上真实响应体再哈希。
用这条命令(注意参数含义):
curl -sL https://cdn.example.com/style.css | openssl dgst -sha384 -binary | openssl base64 -A
关键点:
-
-sL:静默 + 跟随重定向,确保拿到浏览器最终加载的字节流 -
openssl dgst -sha384 -binary:对解压后的明文做哈希,行为与浏览器完全一致 -
openssl base64 -A:避免换行,输出单行 Base64 字符串 - 拼成完整值:例如
sha384-abc123...
HTML 中正确的 <link> 写法
不是“加了就行”,而是属性组合必须精确。以下是最小可靠写法:
<link rel="stylesheet" href="https://cdn.example.com/v1.2.0/main.css" integrity="sha384-abc123..." crossorigin="anonymous">
注意:
-
rel="stylesheet"是生效前提,缺它整个标签不被视为样式表 -
type="text/css"可删,HTML5 中已默认,多写纯属冗余 - 不要用
crossorigin="true"或crossorigin="anonymouse"这类非法值,浏览器直接跳过校验 - 同源 CDN 也必须显式写
crossorigin="anonymous",不能省略
CI/CD 中怎么避免手动维护失效
人工更新 integrity 值极易出错:URL 含 hash 后缀(如 main.a1b2c3.css)或 query 参数(如 ?v=1.2.3)时,一旦资源变更但哈希没重算,SRI 就形同虚设。
自动化方案取决于构建工具:
- Webpack:用
webpack-subresource-integrity插件,自动注入integrity并强制添加crossorigin="anonymous" - Vite / esbuild:需在构建后 hook 步骤——下载产出 CSS、计算 SHA-384、替换 HTML 中对应
<link>的integrity和crossorigin - 关键约束:哈希必须基于最终上线的字节流,不是源码、不是 sourcemap 版本、不是未压缩副本
真正难的不是写那两行属性,而是每次部署时,HTML 里的 integrity 值和 CDN 实际吐出的字节流,差一个 BOM、多一个空格、压错一层,就全盘失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











