Service Worker fetch报错成因及Chrome64升级后问题求助
问题分析与解决方案
首先,咱们来拆解这个错误的核心成因:
这个报错触发的根本原因是**only-if-cached缓存模式有严格的使用限制**——它只能搭配same-origin请求模式使用,并且使用该模式的fetch请求只能从本地缓存获取资源,绝对不允许发起网络请求。
在Chrome 64版本之后,新标签页加载页面时,浏览器会对部分初始导航请求自动设置only-if-cached缓存模式(这是浏览器内部的优化行为)。而你的代码中,当缓存匹配失败后直接复用原请求调用fetch(event.request),这就等于带着only-if-cached模式去发起网络请求,完全违反了规则,自然会抛出错误。
修复后的代码
你需要在发起fetch前,克隆原请求并手动修改它的缓存模式和请求模式,规避浏览器的限制。修改后的代码如下:
self.addEventListener('fetch', function(event) { if (event.request.url.startsWith(self.location.origin)) { event.respondWith( caches.match(event.request).then(function(response) { // 缓存命中直接返回 if (response) { return response; } // 克隆请求并修改模式,避免only-if-cached限制 const fetchRequest = event.request.clone(); return fetch(fetchRequest, { mode: 'same-origin', // 明确指定同源模式 cache: 'default' // 覆盖为默认缓存模式,允许网络请求 }).then(function(fetch_resp){ return fetch_resp; }); }) ); } });
关键细节说明
- 必须克隆请求:
Request对象是可消费的流对象,只能被读取一次,所以必须克隆后才能在caches.match和fetch中重复使用。 - 强制覆盖模式:通过手动设置
mode: 'same-origin'和cache: 'default',确保我们的fetch请求完全符合规则,不会触发浏览器的限制。 - 备选处理方案:如果你想严格遵循
only-if-cached模式的预期,当缓存未命中时可以返回Response.error(),但这种情况会导致页面加载失败,一般不推荐。
内容的提问来源于stack exchange,提问作者N. Dias
相关产品推荐
相关产品推荐

