能,但仅当资源跨域且为script或link标签、integrity值基于cdn实际响应体(解压后无bom utf-8字节)计算、并显式声明crossorigin="anonymous"时才生效。

integrity 属性真能防 CDN 劫持吗?
能,但只在三个条件全部满足时才真正生效:资源必须是跨域的 <script></script> 或 <link rel="stylesheet">;integrity 值必须基于该 CDN 实际返回的响应体(解压后、无 BOM、UTF-8 干净字节)计算;且必须显式声明 crossorigin="anonymous"。漏掉任意一条,浏览器就静默跳过校验——不报错、不阻断、脚本照常执行。
为什么加了 integrity 却没拦住劫持?
大概率不是属性失效,而是根本没触发校验。常见原因包括:
-
crossorigin属性缺失、拼错(如写成crossorigin="true")、或值非法(如空字符串crossorigin="") - 哈希值来自本地文件或在线生成器,而非真实 CDN URL 的响应体(CDN 可能重定向、压缩、按 UA 返回不同内容)
- CDN 响应头不含
Access-Control-Allow-Origin: *,导致 CORS 请求失败,浏览器拿不到响应体 - 使用了错误的哈希前缀(如
SHA384-大写、sha384:冒号结尾),正确写法只有sha256-、sha384-、sha512-(全小写 + 短横)
怎么生成一个靠谱的 integrity 值?
别抄、别猜、别信本地构建产物。唯一可靠方式是用命令行直取线上响应体:
curl -sL https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.global.js | openssl dgst -sha384 -binary | openssl base64 -A
关键点:
-
-sL必须带上:静默模式 + 自动跟随重定向,否则哈希的是 302 响应体 - 不用手动解压:
curl默认自动处理 gzip/Brotli,输出的就是浏览器实际拿到的解压后字节 - 确保 CDN 返回的是无 BOM UTF-8;BOM、末尾换行、多余空格都会让哈希完全不匹配
- 优先选
sha384-:抗碰撞比sha256-更强,所有主流浏览器都支持
样式表 SRI 失效为什么更难发现?
<link rel="stylesheet"> 的 SRI 校验失败不会阻塞渲染,也不会抛红错,只会静默丢弃 CSS,并在 Console 里埋一条 Failed to find a valid digest in the 'integrity' attribute 的 warning(默认可能被过滤掉)。排查时要特别注意:
- 检查 Network 面板里该 CSS 请求的响应头是否含
Content-Encoding: gzip或br:哈希必须基于解压后内容 - HTTP 协议下部分浏览器会直接忽略
integrity,强制走 HTTPS 才能确保校验生效 - 即使同源,也必须显式写
crossorigin="anonymous",否则照样静默失效
真正难的不是加属性,而是每次上线都确保哈希绑定到那个精确字节流——CDN 压缩策略、构建工具差异、甚至 Node.js 版本导致的 base64 编码偏差,都可能让校验翻车。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











