Fetch 不支持 integrity 属性校验,因其属 HTML 解析阶段的浏览器内置行为,而 Fetch 是运行时通用请求 API;需手动实现:用 arrayBuffer 获取二进制、crypto.subtle.digest 计算哈希、base64 编码比对,并通过 blob URL 安全执行。

Fetch 本身不支持 integrity 属性校验,这是 <script> 标签的浏览器内置行为,不是 Fetch API 的功能。想用哈希校验防 CDN 劫持,得手动实现:先用 Fetch 获取脚本内容,再计算其完整哈希值,与预期值比对,一致才执行。
为什么 Fetch 没有 integrity 属性
integrity 是 HTML 规范中为 <link> 和 <script> 标签定义的安全机制,由浏览器在解析 HTML 时自动触发。Fetch 是 JavaScript 运行时发起的通用网络请求,不参与 HTML 解析流程,因此不处理 integrity 校验逻辑。
手动实现哈希校验的步骤
核心思路是:获取脚本原始字节 → 计算 SHA256/SHA384/SHA512 哈希 → 转为 base64 → 与预设值比对
- 用
fetch(url).then(r => r.arrayBuffer())获取二进制数据,避免字符串编码干扰(如 UTF-8 BOM 或换行符差异) - 调用
crypto.subtle.digest('SHA-256', buffer)计算哈希(注意:需在安全上下文如 HTTPS 或 localhost) - 将结果转为 base64 字符串(不是 hex),格式要匹配标准 integrity 值(如
sha256-xxx) - 比对前去掉前缀(如提取
xxx部分),用常数时间比较函数防时序攻击(简单场景可用===,生产环境建议用crypto.timingSafeEqual或等效逻辑)
执行校验后安全地运行脚本
校验通过后不能直接 eval()(不安全且绕过 CSP),推荐方式:
立即学习“Java免费学习笔记(深入)”;
- 创建
URL.createObjectURL(new Blob([buffer], {type: 'application/javascript'})),再动态插入<script src="blob:...">—— 浏览器会按 blob URL 执行,仍受 CSP 约束 - 或用
new Function(code)(),但必须确保 code 是纯字符串且无外部依赖;更稳妥的是把校验后的脚本注入到隔离的<iframe sandbox>中执行 - 若脚本含
import或依赖全局变量,需提前准备执行环境,否则可能报错
实际使用注意事项
这个方案能防篡改,但有局限:
- 无法拦截中间人修改 HTTP 响应头(如删除 CORS 头),需配合 HTTPS 和证书固定
- 哈希值必须和原始构建产物完全一致(包括 source map 注释、末尾换行等),CI/CD 中建议用构建后文件直接生成 integrity 值
- 不支持子资源完整性(SRI)的 fallback 机制(如失败后加载备用源),需自行实现重试或降级逻辑
- 移动端 WebView 或旧版 Safari 可能缺少
csp.subtle支持,需降级处理或提示


















