CacheStorage
注意:此功能在Web Workers中可用。
CacheStorage
接口表示 Cache
对象的存储。
该接口
- 提供所有可由
ServiceWorker
或其他类型的 worker 或window
范围访问的命名缓存的主目录(您不限于仅在 service worker 中使用它)。 - 维护字符串名称到相应
Cache
对象的映射。
使用 CacheStorage.open()
获取 Cache
实例。
使用 CacheStorage.match()
检查给定的 Request
是否是 CacheStorage
对象跟踪的任何 Cache
对象中的键。
您可以通过窗口中的 Window.caches
属性或 worker 中的 WorkerGlobalScope.caches
属性访问 CacheStorage
。
注意:CacheStorage
始终在不受信任的来源(即未使用 HTTPS 的来源,尽管此定义将来可能会变得更复杂)上拒绝并显示 SecurityError
。在 Firefox 上进行测试时,您可以通过检查 Firefox Devtools 选项/齿轮菜单中的在 HTTP 上启用 Service Workers(当工具箱打开时)选项来解决此问题。此外,由于 CacheStorage
需要文件系统访问权限,因此它可能在 Firefox 的隐私模式下不可用。
注意:CacheStorage.match()
是一种便捷方法。可以通过从 CacheStorage.keys()
返回缓存名称数组,使用 CacheStorage.open()
打开每个缓存,并使用 Cache.match()
匹配所需的缓存来实现与缓存条目匹配的等效功能。
实例方法
CacheStorage.match()
-
检查给定的
Request
是否是CacheStorage
对象跟踪的任何Cache
对象中的键,并返回一个解析为该匹配项的Promise
。 CacheStorage.has()
CacheStorage.open()
-
返回一个解析为与
cacheName
匹配的Cache
对象的Promise
(如果该缓存尚不存在,则会创建一个新缓存)。 CacheStorage.delete()
-
查找与
cacheName
匹配的Cache
对象,如果找到,则删除Cache
对象并返回一个解析为true
的Promise
。如果未找到Cache
对象,则解析为false
。 CacheStorage.keys()
-
返回一个将解析为包含与
CacheStorage
跟踪的所有命名Cache
对象对应的字符串的数组的Promise
。使用此方法迭代所有Cache
对象的列表。
示例
此代码片段来自 MDN 的简单 service worker 示例(请参阅正在运行的简单 service worker)。此 service worker 脚本等待 install
事件触发,然后运行 waitUntil
来处理应用程序的安装过程。这包括调用 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;
} else {
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 |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。