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

Service Worker缓存不稳定问题排查求助

Service Worker Fetch Event Error: Non-Response Object Passed to respondWith()

我来帮你排查这个问题——你遇到的错误核心原因是你的Service Worker在fetch事件的respondWith()里返回了非Response对象,具体来说是当网络请求失败且缓存中没有匹配资源时,你返回了undefined,而浏览器要求respondWith()必须接收一个Response实例或者能解析为Response的Promise。

问题代码分析

看你fetch事件处理的最后一段:

.catch(err => caches.match(e.request).then(res => res))

当网络请求失败进入catch后,caches.match(e.request)如果找不到对应的缓存资源,会resolve为undefined。你直接把这个undefined返回给respondWith(),这就触发了浏览器的错误提示:“an object that was not a Response was passed to respondWith()”。

修复方案

你需要确保无论什么情况,respondWith()最终拿到的都是合法的Response对象。修改catch逻辑,当缓存也找不到资源时,返回一个自定义的离线响应:

self.addEventListener('fetch', function (e) {
    console.log("Service Worker: Fetch")
    e.respondWith(
        fetch(e.request)
        .then(res => {
            // Make copy/clone of response
            const responseClone = res.clone()
            // Open Cache
            caches
            .open(cacheName)
            .then(cache => {
                // Add response to cache
                cache.put(e.request, responseClone)
            })
            return response
        }).catch(err => 
            caches.match(e.request).then(res => {
                // 如果缓存有资源就返回,否则返回自定义离线响应
                return res || new Response('<h1>Offline: This resource isn\'t cached</h1>', {
                    headers: { 'Content-Type': 'text/html' }
                })
            })
        )
    )
})

更健壮的缓存策略(可选)

如果想优化用户体验,推荐使用“Cache First, Update in Background”的策略——优先返回缓存资源,同时后台用网络请求更新缓存,这样离线时用户也能看到内容:

self.addEventListener('fetch', function (e) {
    console.log("Service Worker: Fetch");
    e.respondWith(
        caches.match(e.request)
            .then(cachedRes => {
                // 有缓存直接返回,后台悄悄更新缓存
                if (cachedRes) {
                    fetch(e.request).then(networkRes => {
                        caches.open(cacheName).then(cache => {
                            cache.put(e.request, networkRes.clone());
                        });
                    });
                    return cachedRes;
                }
                // 无缓存则走网络,成功后缓存结果
                return fetch(e.request)
                    .then(networkRes => {
                        const responseClone = networkRes.clone();
                        caches.open(cacheName).then(cache => {
                            cache.put(e.request, responseClone);
                        });
                        return networkRes;
                    })
                    .catch(err => {
                        // 网络和缓存都失败,返回统一离线提示
                        return new Response('<h1>Offline Mode: No cached content available</h1>', {
                            headers: { 'Content-Type': 'text/html' }
                        });
                    });
            })
    );
})

额外提示

  • 测试时可以在Chrome DevTools的Application > Cache Storage里查看缓存的资源,确认哪些资源被正确缓存
  • 每次修改Service Worker后,记得更新cacheName(比如改成v3),这样激活时会自动清理旧缓存

内容的提问来源于stack exchange,提问作者Chud37

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:33:12