You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Service Worker缓存CloudFront图片后仍发起网络请求的问题排查

Service Worker缓存CloudFront图片后仍发起网络请求的问题排查

我来帮你梳理下这个问题的可能原因和排查方向,你遇到的情况其实挺常见的,咱们一步步来拆解:

首先先明确几个关键点:你说缓存已经成功存储,但还是看到CloudFront的请求,而且Service Worker里的日志打不出来,还预期看到(disk cache)/memory cache标识——这里先纠正一个误区:Service Worker缓存的资源,在Network面板里不会显示成(disk cache),而是会标注(ServiceWorker),浏览器的HTTP缓存和Service Worker缓存是两个独立的存储区域,这点别搞混了。

接下来看具体问题:

1. 为什么看不到Service Worker里的日志?

这是新手常踩的坑!Service Worker的控制台和页面的控制台是分开的,你在页面F12打开的控制台看不到Service Worker里的console.log输出。你需要:

  • 打开浏览器开发者工具的「Application」标签
  • 在左侧找到「Service Workers」
  • 点击你当前运行的Service Worker旁边的「Inspect」,打开专门的Service Worker控制台,这里才能看到你代码里的日志。

2. 请求有没有被Service Worker拦截到?

你的fetch监听条件是event.request.destination === 'image' && event.request.url.includes("cloudfront.net"),有可能这个条件没匹配到目标请求:

  • 先在Service Worker的fetch监听最开头加一行全局日志:
    console.log(`拦截到请求:destination=${event.request.destination},URL=${event.request.url}`);
    
    然后刷新页面,看目标图片的请求有没有出现在日志里。
  • 检查CloudFront的URL是否带HTTPS?有没有大小写问题?比如URL里是CloudFront.net而不是小写的cloudfront.net?
  • 有些图片请求是通过srcset、picture标签发起的,或者是CSS里的背景图,这类请求的destination是不是image?可以通过上面的日志确认。

3. 缓存匹配为什么失败?

caches.match(event.request)默认是严格匹配,包括请求的方法、Headers(比如Accept头)、URL的查询参数(比如CloudFront可能加的?v=xxx版本号),只要有一点不一样,就匹配不上,会触发网络请求。

你可以放宽匹配条件试试:

caches.match(event.request, {
  ignoreSearch: true, // 忽略URL里的查询参数
  ignoreVary: true    // 忽略响应头里的Vary差异
})

4. Service Worker的状态和作用域有没有问题?

  • 确认Service Worker已经处于「Activated」状态,而不是「Installing」或「Waiting」,可以在Application标签的Service Workers里查看。
  • 检查Service Worker的作用域:如果你的Service Worker是在子目录注册的,可能覆盖不到图片请求的路径(比如图片在根目录,Service Worker在/sw/目录)。注册的时候可以显式指定作用域:
    // 页面里注册Service Worker的代码
    navigator.serviceWorker.register('/sw.js', { scope: '/' });
    

给你修改后的示例代码

结合上面的排查点,调整后的fetch监听代码如下(记得在Service Worker控制台看日志):

const CACHE_NAME = 'image-cache-v1'; // 确保这个变量已经在你的Service Worker里定义了

self.addEventListener('fetch', event => {
  console.log(`拦截到请求:destination=${event.request.destination},URL=${event.request.url}`);
  
  if (event.request.destination === 'image' && event.request.url.includes("cloudfront.net")) {
    event.respondWith(
      caches.match(event.request, {
        ignoreSearch: true,
        ignoreVary: true
      })
        .then(response => {
          console.log(`缓存匹配结果:${response ? '命中' : '未命中'}`);
          if (response) {
            return response; // 返回缓存的图片
          }
          // 缓存未命中,请求网络并缓存
          return fetch(event.request).then(networkResponse => {
            const responseClone = networkResponse.clone();
            caches.open(CACHE_NAME).then(cache => {
              cache.put(event.request, responseClone);
              console.log(`已缓存新图片:${event.request.url}`);
            });
            return networkResponse;
          });
        }).catch(err => {
          console.error('网络请求失败且无缓存:', err);
          // 这里可以返回一张默认 fallback 图片,比如:
          // return fetch('/assets/fallback-image.png');
        })
    );
  }
});

最后,当Service Worker成功返回缓存的图片时,你会在Network面板的Size列看到(ServiceWorker)的标识,而不是你之前预期的(disk cache),这才是正确的状态。

备注:内容来源于stack exchange,提问作者Zach Anton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:25:28