SRI 在 HTML 中声明资源摘要,浏览器加载时自动校验。结合缓存一致性策略,可避免旧版本或错配资源被命中。使用示例<link rel="stylesheet" href="/assets/app.css" integrity="sha256-<HASH>" crossorigin="anonymous"> <script src="/assets/app.js" integrity="sha256-<HASH>" crossorigin="anonymous"></script> 缓存一致性协同构建阶段生成哈希并注入模板,发布时采用哈希命名或 `?v=<HASH>`。Service Worker 在缓存前进行摘要校验,并以哈希为键命名,确保版本一致。async function sha256(bytes) { const buf = await crypto.subtle.digest('SHA-256', bytes); return Array.from(new Uint8Array(buf)).map(x => x.toString(16).padStart(2,'0')).join(''); } const manifest = { '/assets/app.js': '<HASH_JS>', '/assets/app.css': '<HASH_CSS>' }; self.addEventListener('fetch', event => { const url = new URL(event.request.url); if (url.pathname.startsWith('/assets/')) { event.respondWith((async () => { const res = await fetch(event.request); const ab = await res.clone().arrayBuffer(); const hex = await sha256(new Uint8Array(ab)); if (manifest[url.pathname] && manifest[url.pathname] !== hex) return new Response('', { status: 409 }); const cache = await caches.open('assets-hash'); const key = new Request(url.origin + url.pathname + '?v=' + hex, { headers: event.request.headers }); await cache.put(key, res.clone()); return res; })()); } }); 注意事项第三方资源使用 SRI 需 `crossorigin="anonymous"` 且对方支持 CORS。建议将清单生成与校验集成到构建/发布流程。发生摘要不匹配时回退到网络并提示刷新,避免错误缓存。

发表评论 取消回复