Service Worker 可以拦截页面的绝大多数网络请求,但并非所有请求都能被拦截,具体取决于请求的类型、来源以及浏览器的缓存机制。以下是详细分析:
1. 可拦截的请求类型
Service Worker 可以拦截以下类型的请求:
- HTTP/HTTPS 请求:包括
fetch
、XMLHttpRequest
等发起的网络请求。 - 静态资源请求:如 HTML、CSS、JavaScript、图片、字体等文件的请求。
- API 请求:包括 RESTful API、GraphQL 等动态接口请求。
- 跨域请求:Service Worker 可以拦截跨域请求,但需要确保 CORS 配置正确。
- WebSocket 连接请求:Service Worker 可以拦截 WebSocket 的初始握手请求。
- Push 通知请求:Service Worker 可以处理来自服务器的推送通知请求。
2. 不可拦截的请求
以下情况下的请求可能无法被 Service Worker 拦截:
- 内存缓存(Memory Cache)中的资源:浏览器会优先从内存缓存加载资源,此时 Service Worker 无法介入。
- Service Worker 自身脚本的请求:Service Worker 无法拦截自身的更新请求。
- 非同源请求(未正确配置 CORS):默认情况下,Service Worker 只能拦截同源请求,跨域请求需额外处理。
- 浏览器内部请求:如
chrome://
或about:
等特殊协议的请求不受 Service Worker 控制。
3. 拦截的限制
- HTTPS 或 localhost 环境:Service Worker 必须在 HTTPS 或本地开发环境(
localhost
)下运行。 - 作用域限制:Service Worker 只能拦截其注册作用域(
scope
)下的请求。 - 首次加载不受控制:用户首次访问页面时,Service Worker 尚未激活,无法拦截初始请求。
4. 实际应用示例
// service-worker.js
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => {
if (response) {
return response; // 返回缓存
}
return fetch(event.request); // 否则继续网络请求
})
);
});
这段代码展示了 Service Worker 如何拦截 fetch
请求并优先返回缓存内容。
5. 总结
Service Worker 可以拦截页面的绝大多数网络请求,但受限于浏览器缓存策略、同源策略及 HTTPS 要求。合理利用其缓存和请求拦截能力,可以实现离线访问、请求重试、资源优化等功能。