[WebAPIs] Cache API
keywords: Cache API
Cache API 可以用來幫助我們儲存 Request-Response 這種對應關係的資料:
caches
是存在window
的全域物件,用來建立和刪除 Cache Storage 物件。cache
則是從 Cache Storage 中拿出的許多 request-response 對應的項目。
🔖 Using the Cache API @ Google Developers > Web Fundamentals 🔖 Cache API 101 @ bitsofco
建立 Cache 並添加項目(CREATE)
keywords: caches.open(<cache-name)
, cache.add(<request>)
, cache.addAll([<req1>, <req2>])
要建立或存取 cache 物件時需要使用 caches.open(<cache-name>)
:
caches.open('my-cache').then((myCache) => {
// Do stuff with myCache
});
若要在 cache 物件中添加 request-response 的象物,可以使用 cache.add(<request>)
方法,add()
裡面要放 request object 或者單純一個 URL。
caches.open('my-cache').then((myCache) => {
// URL only
myCache.add('/subscribe');
// Full request object
myCache.add(
new Request('/subscribe', {
method: 'GET',
headers: new Headers({
'Content-Type': 'text/html',
}),
/* more request options */
}),
);
});
瀏覽器會根據所給的 Request 發送 Fetch 請求,並且把 response 儲存在瀏覽器的 cache 物件中。
如果想要一次添加許多的項目,可以使用 addAll()
這個方法,它可以接受帶有 requests
的陣列:
caches.open('my-cache').then((myCache) => {
myCache.addAll(['/subscribe', '/assets/images/profile.png']);
});
從 Cache 中讀取檔案(READ)
keywords: caches.match(<request>)
, cache.match(<request>)
, cache.matchAll(<request>)
使用 caches.match(<request>)
可以用來讀取瀏覽器內 Cache Storage 的內容:
caches.match('/subscribe').then((cachedResponse) => {
if (cachedResponse) {
// Do something with cachedResponse
} else {
// Handle if response not found
}
});
caches.match(<request>)
裡面帶的內容是 Request 物件或 URL,而不是該 caches 的名稱。
如果希望從特定名稱的 Cache Storage 中找出特定的 Request,則可以搭配 caches.open()
使用:
caches.open('my-cache').then((myCache) => {
myCache.match('/subscribe').then((cachedResponse) => {
if (cachedResponse) {
// Do something with cachedResponse
} else {
// Handle if response not found
}
});
});
和 addAll()
的方法類似,透過 matchAll()
方法,會將配對到的所有 cached response 以陣列的方式回傳:
caches.open('my-cache').then((myCache) => {
myCache.matchAll('/images/').then((cachedResponses) => {
if (cachedResponses) {
// Do something with cachedResponses
} else {
// Handle if response not found
}
});
});
更新 Cache Storage 內容 (UPDATE)
keywords: cache.add(<request>)
, cache.put(<request>, <response>)
有兩種方式可以更新 Cache Storage 對內容。
第一種是使用 cache.add(<request>)
方法,它會對 request 執行 Fetch,如果同樣的 Request 有新的 response 時,就更新原本的 request 對應到的 response 到 Cache Storage 中:
caches.open('my-cache').then((myCache) => {
// browser will request and cache the response
myCache.add('/subscribe');
});
第二種是使用 cache.put()
方法,如果我們希望更近一步控制要把哪些 response 存入 Cache 中則可以使用這種方法,在使用 cache.put(<request>, <response>)
時,需要同時帶入 request 和對應的 response,也就是說,我們需要自己先使用 fetch 取得 response 後,才能一併帶入 cache.put(<req>, <res>)
方法中。
刪除 Cache Storage 內容(DELETE)
keywords:caches.delete(<cache-name>)
, cache.delete(<request>)
最後,可以使用 cache.delete(<request>)
方法來將 request-response 的 cache 項目從 Cache Storage 中刪除:
caches.open('my-cache').then((myCache) => {
myCache.delete('/subscribe');
});
如果是要把整個 Cache Storage 刪除,則可以使用 caches.delete(<cache-name>)
方法:
caches.delete('my-cache');
檢驗瀏覽器是否支援 Cache API
if ('caches' in window) {
caches.open('my-cache').then((myCache) => {
// Do stuff
});
}
使用在 Service Worker 中
在 service worker 中,我們會使用 Cache API 來發出 request,並且將 response 存在 Cache Storage 中,當同樣的 request 有相同的 response 時,就直接將資料從 Cache Storage 中會應給瀏覽器:
self.addEventListener('fetch', (e) => {
e.respondWith(
// Check if item exists in cache
caches.match(e.request).then((cachedResponse) => {
// If found in cache, return cached response
if (cachedResponse) return cachedResponse;
// If not found, fetch over network
return fetch(e.request);
});
);
});