sri 的 integrity 校验失败时不会触发 onerror,因浏览器直接丢弃响应体;降级需绕过该机制,如 fetch 预检、双源加载或服务端健康路由,且须确保版本、哈希、构建与运维全链路协同。

integrity 属性本身不提供降级能力,它只做校验;CDN 失效时脚本加载失败,浏览器根本不会触发 onerror,也不会执行任何回退逻辑——这是 SRI 的设计原则:宁可白屏,也不执行被篡改的代码。
为什么 onerror 在 integrity 校验失败时不触发
当 integrity 不匹配,浏览器直接丢弃响应体,连脚本解析阶段都不进入,因此 onerror 事件根本不会派发。这不是 bug,是规范强制行为。
- 只有网络请求失败(如 404、503、超时)或 CORS 预检失败时,
onerror才会触发 -
The resource was blocked because integrity check failed是控制台 warning,不是 error 事件 - 试图用
window.addEventListener('error', ...)捕获该失败也无效——它不属于全局 JS 错误范畴
真正可行的 CDN 失效降级方案
必须绕过 SRI 的“静默拒绝”机制,在校验前就完成资源可用性判断或提供备用路径。
- 用
fetch()预检 CDN 资源状态和响应体长度(非完整哈希),成功后再动态插入<script></script>标签 —— 这样可捕获 404/503 并 fallback - 双源加载:一个带
integrity+crossorigin="anonymous"的主 CDN,另一个不带 integrity 的备用 CDN 或本地副本,用document.write或document.head.appendChild动态注入,但需确保备用源可信且版本一致 - 服务端渲染 HTML 时,根据 CDN 健康检查结果(如定期 ping 或 HTTP HEAD 请求)决定注入哪条
<script></script>—— 避免客户端竞态 - 构建时生成两套 HTML:一套含 integrity(默认),一套不含(用于灾备切换),通过 CDN 缓存策略或负载均衡器按健康状态路由
避免踩坑的关键实操点
很多团队尝试用 JS 动态加载 fallback,却在实际部署中翻车。
- 不要在
<script></script>标签里写onerror="loadFallback()"—— 它对 integrity 失败完全无响应 - 备用 CDN 的 URL 必须和主 CDN 同构(相同路径、相同版本号),否则哈希值不通用,无法复用同一套
integrity - 若用
fetch()预检,记得加cache: 'no-store'和超时控制,否则可能缓存 304 或卡死 - 本地 fallback 文件必须和 CDN 版本严格一致(包括 BOM、换行符、压缩方式),否则即使加载成功,也可能因运行时行为差异导致功能异常
最常被忽略的一点:SRI 降级不是前端能单方面解决的问题,它要求 CDN 健康探测、构建流程、HTML 注入时机、甚至运维告警联动全部对齐——否则你写的 fallback 代码,永远等不到执行机会。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











