跳至主要内容

[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);
});

);
});