CacheStorage
注意:此功能在 Web Workers 中可用。
CacheStorage 接口代表 对象的存储。Cache
该接口
- 提供了一个主目录,其中包含所有命名的缓存,这些缓存可以由
或其他类型的 worker 或ServiceWorker作用域访问(您不限于仅将它与 Service Worker 一起使用)。window - 维护一个从字符串名称到相应的
对象的映射。Cache
使用 CacheStorage.open() 来获取一个 实例。Cache
使用 CacheStorage.match() 来检查给定的 是否是 RequestCacheStorage 对象跟踪的任何 对象中的一个键。Cache
您可以通过窗口中的 Window.caches 属性或在 worker 中的 WorkerGlobalScope.caches 属性来访问 CacheStorage。
注意: CacheStorage 始终会在不受信任的源(即未使用的 HTTPS 的源)上因 SecurityError 而拒绝(尽管此定义将来可能会变得更复杂)。在 Firefox 上进行测试时,您可以通过在 Firefox DevTools 的选项/齿轮菜单中选中“在 HTTP 上启用 Service Worker(当工具箱打开时)”选项来绕过此限制。此外,由于 CacheStorage 需要文件系统访问,因此在 Firefox 的私有模式下可能不可用。
注意: CacheStorage.match() 是一个便捷方法。通过从 CacheStorage.keys() 返回缓存名称的数组,使用 CacheStorage.open() 打开每个缓存,并使用 Cache.match() 匹配您想要的缓存,可以实现匹配缓存条目的等效功能。
实例方法
CacheStorage.match()-
检查给定的
是否是RequestCacheStorage对象跟踪的任何对象中的一个键,并返回一个解析为该匹配项的Cache。Promise CacheStorage.has()-
返回一个
,该PromisePromise解析为true,如果存在匹配cacheName的对象。Cache CacheStorage.open()-
返回一个
,该PromisePromise解析为匹配cacheName的对象(如果尚不存在,则创建一个新的缓存)。Cache CacheStorage.delete()-
查找匹配
cacheName的对象,如果找到,则删除该Cache对象并返回一个解析为Cachetrue的。如果未找到Promise对象,则解析为Cachefalse。 CacheStorage.keys()-
返回一个
,它将解析为一个数组,其中包含对应于PromiseCacheStorage跟踪的所有命名对象的字符串。使用此方法可以遍历所有Cache对象列表。Cache
示例
此代码段摘自 MDN 的 简单 Service Worker 示例(请参阅 在线运行的简单 Service Worker)。此 Service Worker 脚本等待 事件触发,然后运行 installwaitUntil 来处理应用程序的安装过程。这包括调用 CacheStorage.open 来创建一个新缓存,然后使用 Cache.addAll 将一系列资源添加到其中。
在第二个代码块中,我们等待 事件触发。我们像这样构造一个自定义响应:FetchEvent
- 检查是否在 CacheStorage 中找到请求的匹配项。如果找到,则提供该匹配项。
- 如果未找到,则从网络获取请求,然后打开第一个块中创建的缓存,并使用
Cache.put将请求的克隆添加到其中(cache.put(event.request, response.clone()))。 - 如果失败(例如,因为网络中断),则返回一个备用响应。
最后,使用 FetchEvent.respondWith 返回最终的自定义响应。
self.addEventListener("install", (event) => {
event.waitUntil(
caches
.open("v1")
.then((cache) =>
cache.addAll([
"/",
"/index.html",
"/style.css",
"/app.js",
"/image-list.js",
"/star-wars-logo.jpg",
"/gallery/bountyHunters.jpg",
"/gallery/myLittleVader.jpg",
"/gallery/snowTroopers.jpg",
]),
),
);
});
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
// caches.match() always resolves
// but in case of success response will have value
if (response !== undefined) {
return response;
}
return fetch(event.request)
.then((response) => {
// response may be used only once
// we need to save clone to put one copy in cache
// and serve second one
let responseClone = response.clone();
caches
.open("v1")
.then((cache) => cache.put(event.request, responseClone));
return response;
})
.catch(() => caches.match("/gallery/myLittleVader.jpg"));
}),
);
});
此代码段展示了如何在 Service Worker 上下文之外使用该 API,并使用 await 运算符使代码更易读。
// Try to get data from the cache, but fall back to fetching it live.
async function getData() {
const cacheVersion = 1;
const cacheName = `myapp-${cacheVersion}`;
const url = "https://jsonplaceholder.typicode.com/todos/1";
let cachedData = await getCachedData(cacheName, url);
if (cachedData) {
console.log("Retrieved cached data");
return cachedData;
}
console.log("Fetching fresh data");
const cacheStorage = await caches.open(cacheName);
await cacheStorage.add(url);
cachedData = await getCachedData(cacheName, url);
await deleteOldCaches(cacheName);
return cachedData;
}
// Get data from the cache.
async function getCachedData(cacheName, url) {
const cacheStorage = await caches.open(cacheName);
const cachedResponse = await cacheStorage.match(url);
if (!cachedResponse || !cachedResponse.ok) {
return false;
}
return await cachedResponse.json();
}
// Delete any old caches to respect user's disk space.
async function deleteOldCaches(currentCache) {
const keys = await caches.keys();
for (const key of keys) {
const isOurCache = key.startsWith("myapp-");
if (currentCache === key || !isOurCache) {
continue;
}
caches.delete(key);
}
}
try {
const data = await getData();
console.log({ data });
} catch (error) {
console.error({ error });
}
规范
| 规范 |
|---|
| Service Workers # cachestorage-interface |
浏览器兼容性
加载中…