ServiceWorker 的 fetch 事件仅拦截同源且页面主动发起的请求(如 fetch、XMLHttpRequest、img 等),不拦截 iframe、跨域无 CORS 的资源、sendBeacon 及 SW 自身安装请求。
ServiceWorker 的 fetch 事件能拦截哪些请求
ServiceWorker 的
事件只拦截同源的、由页面主动发起的网络请求(包括
、
、
、
、
等),但不拦截:
加载、
跨域
不带
头的图片/字体、
、以及 ServiceWorker 自身安装阶段的脚本请求(即
不触发自身
)。
在 fetch 事件里怎么读取和修改请求数据
关键点是:不能直接修改
对象(它是只读的),必须用新构造的
替换;响应体需用
构造,且若要读取原始响应内容(如 JSON),得先调用
或
——否则原
会被消耗掉,无法再返回。
和
可用于
路由
判断
改写 URL 需用
转发请求推荐用
,不是
(会丢失 method/body/headers)
若需缓存并返回,记得设置
,否则
浏览器
可能解析失败
fetch 事件中常见错误和绕不过的坑
最常踩的三个坑:缓存策略误用导致接口永远不更新、
没调用或调用多次、对流式响应(如
)做
解析直接报错。
Comet AI 浏览器
下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。
下载
没调用
→ 请求会走默认网络,但控制台可能无提示
重复调用
→ 报错
对非 JSON 响应调
→
或空对象
使用
后直接
→ 缺少
导致 CORS 失败,应
如何调试 ServiceWorker 的 fetch 拦截行为
Chrome DevTools 的 Application → Service Workers 面板可「Skip waiting」「Update on reload」,但真正看拦截细节得靠
+ 网络面板过滤
类型请求(因为 SW 返回的响应不显示为 XHR/fetch,而是归为
)。更可靠的方式是在 SW 里加日志并配合
查看运行状态。
立即学习
“
前端免费学习笔记(深入)
”;
在 SW 顶部加
确认激活成功
fetch 事件里打日志时用
若请求没进 fetch 事件,先检查是否注册成功、是否在 HTTPS(或 localhost)、是否页面在 SW 控制范围内(
)
ServiceWorker 的
是强大但脆弱的机制,真正难的不是写几行拦截逻辑,而是确保每次响应都携带正确 headers、不破坏原始语义、且在离线/缓存/网络三态间保持行为一致。尤其注意流式响应、重定向、认证头(
)透传这些边界情况,它们往往在灰度期才暴露。
fetchfetch()XMLHttpRequestiframeCORSnavigator.sendBeacon()self.registration.update()fetchrequestRequestResponseresponse.clone().json().text()responseevent.request.urlevent.request.methodnew Request(newUrl, { method, headers, body })fetch(event.request)fetch(event.request.url)headers: { 'Content-Type': 'application/json' }self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname === '/api/data') {
event.respondWith(
fetch(new Request('https://mock-api.example.com/data', {
method: event.request.method,
headers: event.request.headers,
body: event.request.body
}))
.then(res => {
const cloned = res.clone();
return Promise.all([
cloned.json(),
Promise.resolve(res)
]).then(([data, realRes]) => {
console.log('拿到数据:', data);
return realRes;
});
})
);
}
});event.respondWith()text/event-stream.json()event.respondWith()respondWith()Failed to execute 'respondWith' on 'FetchEvent': The event has already been responded to.json()Unexpected tokencache.match()return cacheResheadersreturn new Response(cacheRes.body, cacheRes)console.logOtherOtherchrome://serviceworker-internals/self.addEventListener('activate', e => console.log('SW activated'))console.log('[SW fetch]', event.request.url, event.request.method)navigator.serviceWorker.controller !== nullfetchAuthorization