Service Worker fetch事件监听器传入参数类型错误问题
问题根本原因
你自定义的fetch事件处理函数和浏览器全局的fetch请求API重名了,导致函数递归调用时入参异常。
- 首次执行:
fetch作为事件监听回调,入参是正常的FetchEvent对象 - 后续执行:你在
process函数中调用fetch(e.request.clone())时,调用的不是原生网络请求API,而是你自己定义的这个处理函数,此时传入的参数是克隆后的Request对象而非事件对象,所以出现你观察到的多余Request对象打印。调用e.request.url时,Request对象本身没有request属性,自然会抛出异常。
修复方案
把自定义的处理函数重命名为不与全局API冲突的名称即可,比如onFetch,修改后的代码如下:
事件监听代码
self.addEventListener('fetch', onFetch)
处理函数代码
const onFetch = e => { console.log({e}) if (!e.request.url.startsWith(self.location.origin) || e.request.method !== 'GET') return const save = async res => { // 注意补充dynamic缓存名称的定义,避免变量未定义错误 const cache = await caches.open('dynamic') cache.put(e.request, res) } const process = async cached => { if (cached) return cached // 此处调用的就是原生fetch API了 const res = await fetch(e.request.clone()) if (res) await save(res.clone()) return res } e.respondWith(caches.match(e.request).then(process)) }
额外注意事项
你原代码中caches.open(dynamic)的dynamic变量没有显式定义,建议补充为字符串常量或者提前定义变量,避免额外的运行时错误。
内容的提问来源于stack exchange,提问作者Will
相关产品推荐
相关产品推荐

