当你在 Service Worker 中缓存 API 数据时,如何管理缓存过期、更新等策略?
在 Service Worker 中处理 API 请求的缓存和过期策略,通常涉及几个关键步骤:拦截网络请求、检查缓存状态、更新缓存以及设置缓存过期策略。以下是一些基本步骤和示例代码,展示如何在 Service Worker 中实现这些功能:
使用 Service Worker 的 fetch
事件来拦截所有或特定网络请求。
self.addEventListener('fetch', function(event) {
const request = event.request;
// 检查请求的 URL 是否需要被缓存处理
if (shouldCache(request.url)) {
event.respondWith(cacheAndNetworkRace(request));
} else {
// 不需要缓存的请求直接放行
event.respondWith(fetch(request));
}
});
function shouldCache(url) {
// 根据 URL 判断是否需要缓存
return url.startsWith('https://api.example.com/');
}
实现一个 cacheAndNetworkRace
函数,该函数尝试从缓存获取资源,同时发起网络请求。一旦其中一个响应返回,就使用它,但网络请求仍然继续以更新缓存。
async function cacheAndNetworkRace(request) {
try {
const cacheResponse = await caches.match(request);
if (cacheResponse) {
// 尝试从网络获取最新版本,但不等待它完成
fetch(request).then(response => {
if (response.ok) {
caches.open('my-cache-name').then(cache => {
cache.put(request, response.clone());
});
}
});
return cacheResponse;
}
const networkResponse = await fetch(request);
if (!networkResponse.ok) {
throw new Error('Network response was not ok');
}
// 缓存响应
const cache = await caches.open('my-cache-name');
cache.put(request, networkResponse.clone());
return networkResponse;
} catch (error) {
// 处理错误
console.error('Fetch error:', error);
throw error;
}
}
缓存的过期策略可以在存储缓存项时设置,但 Service Workers 原生不支持设置 TTL(Time-To-Live)。你需要自己管理过期逻辑。
一种方法是在缓存时添加一个时间戳,并在每次请求时检查时间戳来决定是否从网络重新获取数据。
async function updateWithTimestamp(request, response) {
const cache = await caches.open('my-cache-name');
// 将响应和时间戳一起存储
const timestampedResponse = new Response(response.body, response);
timestampedResponse.headers.append('X-Timestamp', new Date().toISOString());
cache.put(request, timestampedResponse);
}
// 在获取缓存时检查时间戳
async function checkAndRefreshIfNeeded(request) {
const cacheResponse = await caches.match(request);
if (cacheResponse && !isExpired(cacheResponse)) {
return cacheResponse;
}
// 如果过期,则发起网络请求并更新缓存
// 这里使用 cacheAndNetworkRace 或直接 fetch 更新
}
function isExpired(response) {
const timestamp = new Date(response.headers.get('X-Timestamp'));
// 假设我们设置 1 小时过期
return (new Date() - timestamp) / 36e5 > 1;
}
注意:Response
对象是不可变的,所以你需要创建一个新的 Response
对象来添加或修改头部信息。
通过拦截请求、管理缓存和网络竞争,以及设置缓存过期策略,你可以有效地在 Service Worker 中处理 API 请求的缓存和过期。上述代码示例提供了基本的框架,但你可能需要根据自己的具体需求进行调整和优化。
8 回答4.7k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
6 回答2.3k 阅读
5 回答6.3k 阅读✓ 已解决
5 回答1.3k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答1.4k 阅读✓ 已解决
在 Service Worker 中缓存 API 数据时,可以通过
Cache-Control
和stale-while-revalidate
等 HTTP 头来管理缓存过期策略。另外,你可以手动在 Service Worker 中设置缓存的有效期,并在过期时自动更新: