Web应用离线缓存修改存入异常:条目无效无法匹配获取
解决Service Worker缓存自定义响应时Content-Length为0、无法匹配的问题
你遇到的这个问题很典型,核心原因是Response构造函数的参数格式错误,再加上几个细节没处理到位,导致缓存无法正确识别和存储你的自定义响应。我来一步步帮你排查修复:
问题根源分析
你提到Chrome预览面板能显示正确对象,但缓存条目显示Content-Length: 0、时间为1970年,且cache.match()返回undefined,这说明你创建的Response对象不符合规范,缓存系统无法正确解析它的元数据和响应体。
你的代码中的关键错误
看你创建Response的这一行:
var resACachear = new Response(blob1, { "status": 200, myHeaders });
这里的headers参数写法完全错误!Response构造函数的第二个参数是配置对象,其中headers必须通过headers键明确指定,你直接写myHeaders相当于没有传入有效的headers配置,这会导致Response初始化异常,进而让缓存无法正确计算响应体长度。
分步修复方案
- 修正Response构造函数参数(最关键)
把创建Response的代码改成:
var resACachear = new Response(blob1, { status: 200, headers: myHeaders // 必须明确指定headers键 });
这样Response才能正确关联你的请求头,缓存系统也能正确识别响应体的Content-Length。
- 验证Blob的有效性
虽然预览显示正确,但建议确认Blob的内容是否正常:
console.log('Blob内容大小:', blob1.size); // 正常情况下应该大于0
如果size为0,检查nuevaMed对象是否有有效数据,JSON.stringify(nuevaMed)是否返回了非空字符串。
- 确保缓存键的一致性
你创建的urlACachear要和后续cache.match()使用的请求URL完全一致(包括协议、域名、路径、查询参数)。如果urlBase是相对路径,可能导致URL解析异常,建议使用绝对URL:
// 确保urlBase是绝对路径,比如 window.location.origin + '/api' var urlACachear = new URL(`obra/${nuevaMed.obraId}/mediciones/${nuevaMed.id}`, urlBase); // 打印确认URL格式 console.log('缓存目标URL:', urlACachear.href);
后续调用cache.match()时,要使用完全相同的URL或Request对象:
cache.match(urlACachear.href) // 直接传入URL字符串或urlACachear对象均可
- 优化代码可读性(可选)
你的代码里多次使用clone(),虽然功能没问题,但可以简化不必要的克隆,让代码更清晰:
return caches.open(CACHE_NAME).then(cache => { return cache.matchAll().then(responses => { const resp = responses[0]; return resp.json().then(datosResp => { const nuevaMed = nuevaMedicionDesdeMedicion(datosResp); const urlACachear = new URL(`obra/${nuevaMed.obraId}/mediciones/${nuevaMed.id}`, urlBase); const nuevaMedJSON = JSON.stringify(nuevaMed); const blob1 = new Blob([nuevaMedJSON], { type: "application/json;charset=utf-8" }); const myHeaders = new Headers(resp.headers); // 修正后的Response创建 const resACachear = new Response(blob1, { status: 200, headers: myHeaders }); return cache.put(urlACachear, resACachear).then(() => { // 可返回需要的数据供后续逻辑使用 return resACachear; }); }); }); });
修复后验证
修改完成后,重新注册Service Worker、清空旧缓存,然后测试:
- 在Chrome开发者工具的Application > Cache Storage中查看缓存条目,应该能看到正确的Content-Length和当前缓存时间
- 调用
cache.match(urlACachear)应该能正常返回对应的Response对象
另外,还要确认你的Service Worker作用域覆盖了目标URL,避免因作用域限制导致缓存无法访问。
内容的提问来源于stack exchange,提问作者MikMik
相关产品推荐
相关产品推荐

