sri对有效,但必须同时设置integrity和crossorigin="anonymous",否则浏览器静默忽略校验;哈希须基于cdn真实响应体(解压后)用sha384计算,仅script和该link标签支持。

SRI 对 <link rel="stylesheet"> 有效,但漏写 crossorigin 或哈希算错,浏览器就静默丢样式——连报错都没有。
为什么加了 integrity 却没生效
最常见原因是没写 crossorigin 属性。浏览器只对跨域请求启用 SRI 校验,而 <link rel="stylesheet"> 默认是 CORS-ineligible 请求(不带 CORS 头),此时 integrity 完全被忽略。
-
crossorigin="anonymous"是推荐写法,Firefox 解析更稳;crossorigin=""效果相同但兼容性略弱 -
crossorigin="use-credentials"会直接禁用 SRI,哪怕哈希完全正确也跳过校验 - CDN 响应头必须含
access-control-allow-origin: *(或具体域名),否则浏览器拒绝读取响应体做哈希比对 - 如果 CDN 返回了
Content-Encoding: gzip或br,你却用未压缩的本地文件算 hash,必然失败
怎么生成靠谱的 integrity 值
别用本地文件直接算 hash。CDN 实际返回的内容可能含 BOM、换行差异、gzip 压缩、重定向甚至 HTML 错误页——这些都会让哈希不匹配。
- 用线上真实响应体计算:
curl -sL https://cdn.example.com/style.css | openssl dgst -sha384 -binary | openssl base64 -A - 确保命令输出无多余空格或换行;拼成
sha384-<base64></base64>格式 - 只用
sha384(当前抗碰撞最优),禁用sha256(冲突风险上升)、sha1或md5(已不安全) - 若 CDN URL 含 query 参数(如
?v=1.2.3)或 hash 后缀(如style.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",防止自己服务器被篡改
CI/CD 中怎么避免手动维护 integrity
人工更新哈希值不可靠,尤其当构建产物路径动态变化时,SRI 就形同虚设。
- Webpack 用户可用
webpack-subresource-integrity插件,自动注入integrity并强制添加crossorigin="anonymous" - Vite 项目可用
vite-plugin-sri(截至 2026 年 10 月已支持<link>标签) - 纯 HTML 部署场景,建议把哈希生成逻辑封装进构建脚本,和 CDN URL 一起从同一份配置读取,杜绝手误
- 上线前必查 Network 面板:确认 CSS 请求响应头含
access-control-allow-origin,且响应体确实是 CSS 内容(Content-Type: text/css)
真正容易被忽略的是:SRI 失败时浏览器只记一条 warning 日志,且默认被 Console 过滤掉。打开 DevTools → Console → Filter → 勾选「Warnings」才能看到 Failed to find a valid digest in the 'integrity' attribute。页面样式崩了却控制台一片空白,就是这个原因。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











