Cache

Cache インターフェイスは、Request / Response オブジェクトのペアのためのストレージの仕組みを提供します。例えば、 ServiceWorker のライフサイクルの一部としてこれらをキャッシュします。なお、 Cache インターフェイスは、ワーカーだけでなくウィンドウスコープにも公開されています。サービスワーカーの仕様書で定義されているものですが、必ずしもサービスワーカーとの組み合わせで使用する必要はありません。

単一のオリジンが、複数の名前付き Cache オブジェクトを持つことができます。 (例えば ServiceWorker の中などで) スクリプトがどのように Cache を更新するかを実装する必要があります。 Cache 内のアイテムは、明示的に要求しない限り更新されませんし、削除しない限り有効期限はありません。 CacheStorage.open() を使用して特定の名前付き Cache オブジェクトを開き、それから任意の Cache のメソッドを呼び出して Cache を管理します。

また、定期的にキャッシュエントリを一掃する必要があります。各ブラウザーは、指定されたオリジンが使用できるキャッシュストレージの総量に厳しい制限を設けています。キャッシュ容量の概算の使用量は StorageEstimate API を用いて確認することができます。ブラウザーはディスク容量の管理に最善を尽くしますが、あるオリジンのキャッシュストレージを削除することがあります。ブラウザーはふつう、あるオリジンのデータをすべて削除するか、まったく削除しないかのいずれかです。名前を用いてキャッシュをバージョン管理し、安全に操作できるスクリプトのバージョンからのみキャッシュを使用するようにしてください。詳細は、古いキャッシュの削除を確認してください。

メモ: キーの照合アルゴリズムは、値の中にある VARY ヘッダーに依存しています。そのため、新しいキーを照合するには、キャッシュ内のエントリのキーと値の両方を調べる必要があります。

メモ: キャッシュ API は HTTP のキャッシュヘッダーを尊重しません。

メソッド

Cache.match(request, options)
Cache オブジェクトで最初に一致したリクエストに関連するレスポンスで解決する Promise を返します。
Cache.matchAll(request, options)
Cache オブジェクトで一致するすべてのリクエストの配列で解決する Promise を返します。
Cache.add(request)
URL を受け取り、それを取得して、指定されたキャッシュに結果のレスポンスオブジェクトを追加します。機能的には fetch() を呼び出してから、 put() を使用してキャッシュに結果を追加するのと同等です。
Cache.addAll(requests)
URL の配列を受け取り、それらを取得して指定されたキャッシュに結果のレスポンスオブジェクトを追加します。
Cache.put(request, response)
リクエストとそのレスポンスの両方を受け取り、指定されたキャッシュへ追加します。
Cache.delete(request, options)
キーがリクエストである Cache エントリを探し、見つかった場合は Cache エントリを削除して、 true で解決する Promise を返します。 Cache エントリが見つからない場合、Promise は false で解決します。
Cache.keys(request, options)
Cache キーの配列で解決する Promise を返します。

このコードスニペットは、service worker selective caching sample からのものです (selective caching をライブで見る)。このコードでは CacheStorage.open() を使用して、 font/ で始まる Content-Type ヘッダー用の Cache オブジェクトを開きます。

そしてこのコードは、 Cache.match() を使用してすでにキャッシュ内に一致するフォントがあるかどうかを確認し、もしあれば、それを返します。一致するフォントがなかった場合は、コードはネットワークからフォントを取得して、 Cache.put() を用いて取得したリソースをキャッシュします。

このコードは fetch() の操作で発生する例外を処理します。なお、 HTTP のエラーレスポンス (404 など) はこの例外を発生させません。適切なエラーコードを持つ通常のレスポンスオブジェクトを返します。

このコードスニペットでは、サービスワーカーで使用されるバージョン付きキャッシュのベストプラクティスも示しています。この例ではキャッシュが1つしかありませんが、キャッシュが複数でも同じアプローチが利用できます。これはキャッシュの一括指定識別子を、具体的なバージョン付けされたキャッシュ名に対応させます。このコードはまた、 CURRENT_CACHES で名前が指定されていないキャッシュをすべて削除します。

このコード例において、 cachesServiceWorkerGlobalScope のプロパティです。これは CacheStorage オブジェクトを保持し、 CacheStorage インターフェイスでアクセスすることができます。これは WindowOrWorkerGlobalScope ミックスインを実装したものです。

メモ: Chrome では、 chrome://inspect/#service-workers にアクセスして、登録されたサービスワーカーの下の "inspect" リンクをクリックすると、 service-worker.js スクリプトが行う様々なアクションのログ状態を見ることができます。
var CACHE_VERSION = 1;
var CURRENT_CACHES = {
  font: 'font-cache-v' + CACHE_VERSION
};

self.addEventListener('activate', function(event) {
  // CURRENT_CACHES で指定されていないすべてのキャッシュを削除します。
  // この例ではキャッシュは1つしかありませんが、同じロジックが
  // 複数のバージョン化されたキャッシュがある場合を処理します。
  var expectedCacheNamesSet = new Set(Object.values(CURRENT_CACHES));
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (!expectedCacheNamesSet.has(cacheName)) {
            // このキャッシュ名が「予期される」キャッシュ名のセットに存在しない場合は、削除します。
            console.log('Deleting out of date cache:', cacheName);
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

self.addEventListener('fetch', function(event) {
  console.log('Handling fetch event for', event.request.url);

  event.respondWith(
    caches.open(CURRENT_CACHES.font).then(function(cache) {
      return cache.match(event.request).then(function(response) {
        if (response) {
          // event.request のエントリがキャッシュにある場合、レスポンスが定義され、それを返すことができます。
          // この例では、フォントリソースのみがキャッシュされることに注意してください。
          console.log(' Found response in cache:', response);

          return response;
        }

        // それ以外の場合、event.request のエントリがキャッシュにない場合、
        // レスポンスは undefined となり、リソースを fetch() する必要があります。
        console.log(' No response for %s found in cache. About to fetch ' +
          'from network...', event.request.url);

        // 後で cache.put() の呼び出しで使用する可能性があるため、リクエストで .clone() を呼び出します。
        // fetch() とcache.put() の両方がリクエストを「消費」するため、コピーを作成する必要があります。
        // (https://fetch.spec.whatwg.org/#dom-request-clone を参照)
        return fetch(event.request.clone()).then(function(response) {
          console.log('  Response for %s from network is: %O',
            event.request.url, response);

          if (response.status < 400 &&
              response.headers.has('content-type') &&
              response.headers.get('content-type').match(/^font\//i)) {
            // これにより、エラーであることがわかっているレスポンス(つまり、HTTP ステータスコード 4xx または 5xx)のキャッシュが回避されます。
            // また、フォントに対応するレスポンスのみをキャッシュする必要があります。
            // つまり、"font/" で始まる Content-Type レスポンスヘッダーを持ちます。
            // 不透明なフィルタされたレスポンス(https://fetch.spec.whatwg.org/#concept-filtered-response-opaque)の場合、
            // レスポンスヘッダーにアクセスできないので、このチェックは常に失敗し、フォントはキャッシュされないことに注意してください。
            // すべての Google Web Fonts は CORS をサポートするドメインから提供されるため、ここでは問題になりません。
            // ただし、CORS をサポートしていないクロスオリジンドメインから他のリソースをキャッシュしようとしている場合は、注意が必要です。
            // レスポンスで .clone() を呼び出して、そのコピーをキャッシュに保存します。
            // そうすることで、制御されたページに戻る元のレスポンスオブジェクトを保持できます。
            // (https://fetch.spec.whatwg.org/#dom-response-clone を参照)
            console.log('  Caching the response to', event.request.url);
            cache.put(event.request, response.clone());
          } else {
            console.log('  Not caching the response to', event.request.url);
          }

          // 元のレスポンスオブジェクトを返します。これは、リソース要求を満たすために使用されます。
          return response;
        });
      }).catch(function(error) {
        // この catch() は、match() または fetch() 操作から発生する例外を処理します。
        // HTTP エラーレスポンス(404 など)は例外をトリガーしないことに注意してください。
        // 適切なエラーコードが設定された通常のレスポンスオブジェクトを返します。
        console.error('  Error in fetch handler:', error);

        throw error;
      });
    })
  );
});

クッキーのキャッシュへの格納

Fetch API では Set-Cookie ヘッダーを、 Response オブジェクトを fetch() から返す前に削除する必要があります。したがって、キャッシュに含まれる Response はヘッダーを含みません。

仕様書

仕様書 状態 備考
Service Workers
Cache の定義
草案 初回定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung Internet
Cache
実験的
Chrome 完全対応 43
補足
完全対応 43
補足
補足 From 40 to 42, this was only available on service workers.
Edge 完全対応 ≤18Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 30
補足
完全対応 30
補足
補足 From 27 to 29, this was only available on service workers.
Safari 完全対応 11WebView Android 完全対応 43
補足
完全対応 43
補足
補足 From 40 to 42, this was only available on service workers.
Chrome Android 完全対応 43
補足
完全対応 43
補足
補足 From 40 to 42, this was only available on service workers.
Firefox Android 完全対応 39Opera Android 完全対応 30
補足
完全対応 30
補足
補足 From 27 to 29, this was only available on service workers.
Safari iOS 完全対応 11Samsung Internet Android 完全対応 4.0
補足
完全対応 4.0
補足
補足 From 40 to 42, this was only available on service workers.
add
実験的
Chrome 完全対応 44
補足
完全対応 44
補足
補足 Requires HTTPS from version 46.
Edge 完全対応 16Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 31
補足
完全対応 31
補足
補足 Requires HTTPS from version 33.
Safari 完全対応 11WebView Android 完全対応 44
補足
完全対応 44
補足
補足 Requires HTTPS from version 46.
Chrome Android 完全対応 44
補足
完全対応 44
補足
補足 Requires HTTPS from version 46.
Firefox Android 完全対応 39Opera Android 完全対応 32
補足
完全対応 32
補足
補足 Requires HTTPS from version 33.
Safari iOS 完全対応 11Samsung Internet Android 完全対応 4.0
補足
完全対応 4.0
補足
補足 Requires HTTPS from Samsung Internet 5.0.
addAll
実験的
Chrome 完全対応 46
補足
完全対応 46
補足
補足 Requires HTTPS.
Edge 完全対応 16Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 33
補足
完全対応 33
補足
補足 Requires HTTPS.
Safari 完全対応 11WebView Android 完全対応 46
補足
完全対応 46
補足
補足 Requires HTTPS.
Chrome Android 完全対応 46
補足
完全対応 46
補足
補足 Requires HTTPS.
Firefox Android 完全対応 39Opera Android 完全対応 33
補足
完全対応 33
補足
補足 Requires HTTPS.
Safari iOS 完全対応 11Samsung Internet Android 完全対応 5.0
補足
完全対応 5.0
補足
補足 Requires HTTPS.
delete
実験的
Chrome 完全対応 43Edge 完全対応 16Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 30Safari 完全対応 11WebView Android 完全対応 43Chrome Android 完全対応 43Firefox Android 完全対応 39Opera Android 完全対応 30Safari iOS 完全対応 11Samsung Internet Android 完全対応 4.0
keys
実験的
Chrome 完全対応 43Edge 完全対応 16Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 30Safari 完全対応 11WebView Android 完全対応 43Chrome Android 完全対応 43Firefox Android 完全対応 39Opera Android 完全対応 30Safari iOS 完全対応 11Samsung Internet Android 完全対応 4.0
match
実験的
Chrome 完全対応 43Edge 完全対応 16Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 30Safari 完全対応 11WebView Android 完全対応 43Chrome Android 完全対応 43Firefox Android 完全対応 39Opera Android 完全対応 30Safari iOS 完全対応 11Samsung Internet Android 完全対応 4.0
matchAll
実験的
Chrome 完全対応 47Edge 完全対応 16Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 34
補足
完全対応 34
補足
補足 Requires HTTPS.
Safari 完全対応 11WebView Android 完全対応 47Chrome Android 完全対応 47Firefox Android 完全対応 39Opera Android 完全対応 34Safari iOS 完全対応 11Samsung Internet Android 完全対応 5.0
put
実験的
Chrome 完全対応 43
補足
完全対応 43
補足
補足 Requires HTTPS from version 46.
Edge 完全対応 16Firefox 完全対応 39
補足
完全対応 39
補足
補足 Extended Support Releases (ESR) before Firefox 78 ESR do not support service workers and the Push API.
IE 未対応 なしOpera 完全対応 30
補足
完全対応 30
補足
補足 Requires HTTPS from version 33.
Safari 完全対応 11WebView Android 完全対応 43
補足
完全対応 43
補足
補足 Requires HTTPS from version 46.
Chrome Android 完全対応 43
補足
完全対応 43
補足
補足 Requires HTTPS from version 46.
Firefox Android 完全対応 39Opera Android 完全対応 30
補足
完全対応 30
補足
補足 Requires HTTPS from version 33.
Safari iOS 完全対応 11Samsung Internet Android 完全対応 4.0
補足
完全対応 4.0
補足
補足 Requires HTTPS from Samsung Internet 5.0.

凡例

完全対応  
完全対応
未対応  
未対応
実験的。動作が変更される可能性があります。
実験的。動作が変更される可能性があります。
実装ノートを参照してください。
実装ノートを参照してください。

関連情報