integrity 和 crossorigin="anonymous" 必须同时存在,缺一不可;否则浏览器静默忽略校验,仅输出被默认过滤的 warning 日志,导致样式丢失且无明显报错。

integrity 和 crossorigin="anonymous" 必须同时存在,缺一不可;否则浏览器静默忽略校验,样式丢失且控制台不报红错——只有一条被默认过滤的 warning。
为什么加了 integrity 却没效果?
浏览器默认把 <link rel="stylesheet"> 当作非 CORS 请求处理,而 SRI 只在 CORS 流程中触发校验。漏写 crossorigin,或写成 crossorigin=""(Firefox 解析不稳定)、crossorigin="true"(非法值),都会导致 integrity 被彻底忽略。
-
crossorigin="anonymous"是公开 CDN 的唯一推荐写法:它让浏览器带上 Origin 头,CDN 才会返回Access-Control-Allow-Origin: *等必要响应头 -
crossorigin="use-credentials"会直接禁用 SRI,哪怕哈希完全正确也跳过校验 - 哪怕资源是同源的(比如你自建的 CDN),也必须显式声明
crossorigin="anonymous"
怎么生成真正可用的 integrity 值?
本地文件、网页生成器、npm 包里抄的哈希,基本都不可靠。CDN 实际返回的内容可能被 gzip/brotli 压缩、重定向、加 BOM、按 UA 返回不同版本——这些都会让哈希失配。
- 唯一可信方式:
curl -sL https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css | openssl dgst -sha384 -binary | openssl base64 -A - 输出结果拼成
sha384-xxx格式,注意-A防止 base64 换行 - 必须用
sha384:比sha256抗碰撞更强,Chrome/Firefox/Edge 全支持;sha1和md5已不安全,禁用 - 若 CDN URL 含 query 参数(如
?v=1.2.3)或 hash 后缀(如main.a1b2c3.css),每次构建后必须重算哈希,不能复用旧值
CDN 失败时如何回退而不破坏 SRI?
靠 onerror 回退本地 CSS 是最轻量、兼容性最好的方案,且与 SRI 共存无副作用——SRI 只在校验失败时阻止加载,不影响 onerror 触发。
- 给
<link>加id,比如id="bootstrap-cdn" - 在
底部加内联 JS:document.getElementById('bootstrap-cdn').onerror = () => { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = '/css/bootstrap.min.css'; document.head.appendChild(link); }; - 本地路径必须是服务器可访问的真实路径(如
/css/),不能是./css/或../css/,尤其在 SPA 路由下易 404 - 本地 CSS 文件也建议加
integrity和crossorigin="anonymous",防止自己服务器被篡改
排查 SRI 失效时最容易被忽略的点
SRI 失效时浏览器不会中断渲染、不抛异常、不触发 onerror,只会静默丢弃该 CSS,并在 Console 记一条 warning 级日志:Failed to find a valid digest in the 'integrity' attribute。这条日志默认被过滤掉,极容易被忽略。
立即学习“前端免费学习笔记(深入)”;
- 打开 DevTools → Console → 右上角「Filter」→ 勾选「Warnings」才能看到
- 检查 Network 面板里对应 CSS 请求的 Response Headers:
access-control-allow-origin是否存在、content-encoding是否为gzip或br(哈希必须基于解压后字节) - 直接在浏览器地址栏打开你的
href值,确认响应头含Content-Type: text/css,且响应体是纯 CSS 内容(不是 HTML 错误页) - 确保 CDN 域名已在 CSP 的
style-src中放行,否则请求根本发不出去


















