integrity属性不配crossorigin就等于没写,浏览器仅在CORS模式下校验,必须显式声明crossorigin="anonymous"且哈希基于真实CDN响应体计算,仅script和link[rel=stylesheet]支持,失败时脚本静默丢弃。

integrity 属性不配 crossorigin 就等于没写
浏览器看到 integrity 属性后,不会立刻校验,而是强制走 CORS 流程——但前提是显式声明 crossorigin。漏写、写成 crossorigin="true" 或 crossorigin=""(Firefox 下行为不一致),都会导致 SRI 静默失效:脚本照常加载,控制台无警告,白屏或异常时极难定位。
公开 CDN(如 jsDelivr、unpkg、cdnjs)一律用 crossorigin="anonymous";只有你自己的后端要求带 Cookie 加载资源时,才考虑 crossorigin="use-credentials",且服务端必须同步返回 Access-Control-Allow-Credentials: true 和明确域名的 Access-Control-Allow-Origin(不能是 *)。
哈希值必须从线上真实响应体计算,不是本地文件也不是在线生成器
CDN 可能重定向、返回 gzip/Brotli 压缩内容、插入 BOM、或按 User-Agent 返回不同版本。本地下载的 .js、构建产物、复制粘贴的他人哈希、甚至 srihash.org 算出的值,只要与浏览器最终请求到的字节流不一致,SRI 就必然失败。
可靠命令(自动跟随重定向、解压、无换行):
curl -sL https://cdn.example.com/app.js | openssl dgst -sha384 -binary | openssl base64 -A
注意:-A 是关键,防止 base64 输出换行符导致 integrity 值非法。
只对 <script src> 和 <link rel="stylesheet"> 生效
以下写法全部无效,浏览器直接忽略 integrity 属性,不报错也不校验:
-
<script>console.log()</script>(内联脚本) <img src="" integrity="">-
<link rel="icon">或<link rel="preload"> -
document.createElement('script')后手动设src和integrity -
fetch()、import()、<iframe>
SRI 是 HTML 解析阶段的静态机制,仅覆盖两类标签,其他路径需靠 CSP、调用栈验证等补充防护。
SRI 失败时脚本被静默丢弃,不触发 onerror
校验失败时,浏览器不会执行脚本,也不会调用 onerror 回调,控制台仅提示一句模糊错误:
Failed to find a valid digest in the 'integrity' attribute
这意味着:若你依赖该脚本初始化核心功能(比如 SecureMonitor),它不执行,后续逻辑就直接断链——没有 fallback,也没有可观测入口。务必在部署前用篡改哈希的方式实测阻断效果,并确认监控/降级逻辑已前置到 SRI 脚本之外。
真正容易被忽略的是:SRI 只保“字节一致”,不保“语义安全”。哪怕哈希匹配,脚本仍可能被原型污染、事件监听劫持或动态 eval 绕过。全链路防劫持必须叠加对象冻结、工厂函数初始化、WeakMap 绑定和调用栈实时验证——这些都得在 SRI 通过后的脚本内部完成,且不能暴露可覆盖的全局实例。

















