CacheStorage - 表示 Cache 对象的存储

CacheStorage 接口表示 Cache 对象的存储。

该接口:

使用 CacheStorage.open() 获得 Cache 实例。

使用 CacheStorage.match() 来检查给定的 Request 是否是 CacheStorage 对象跟踪的任何 Cache 对象中的键。

您可以通过全局 caches 属性访问 CacheStorage

注意CacheStorage 总是在不受信任的来源(即那些不使用 HTTPS 的应用程序,尽管将来这种定义可能会变得更加复杂)上以 SecurityError 拒绝。在测试时,您可以通过检查 Firefox Devtools 选项 / 齿轮菜单中的 “通过 HTTP 启用 Service Workers(打开工具箱时)” 选项来解决此问题。

注意CacheStorage.match() 是一个快捷方法。可以通过以下方式实现与缓存条目匹配的等效功能:从 CacheStorage.keys() 返回一组缓存名称,使用 CacheStorage.open() 打开每个缓存,然后使用 Cache.match() 匹配所需的缓存。

方法

CacheStorage.match()

检查给定的 Request 对象是否是 CacheStorage 对象跟踪的 Cache 对象中的键,返回一个 Promise,解析为该匹配项。

CacheStorage.has()

返回一个 Promise,如果存在与 cacheName 相匹配的Cache 对象,则解析为 true

CacheStorage.open()

返回一个 Promise,它解析为与 cacheName 相匹配的 Cache 对象(如果尚不存在,则会创建一个新的缓存。)

CacheStorage.delete()

查找与 cacheName 匹配的 Cache 对象,如果找到,则删除 Cache 对象,并返回一个 Promise 解析为 true。如果没有找到 Cache 对象,则解析为 false

CacheStorage.keys()

返回一个 Promise,该数组将解析为包含与 CacheStorage 跟踪的所有命名 Cache 对象相对应的字符串的数组。使用此方法可以迭代所有 Cache 对象的列表。

实例

此代码段来自 sw-test 实例(请参阅 sw-test 在线运行。)此服务工作线程脚本等待 InstallEvent 触发,然后运行 waitUntil 来处理应用程序的安装过程。它包括调用 CacheStorage.open 创建新的缓存,然后使用 Cache.addAll 向其中添加一系列资源。

在第二个代码块中,我们等待 FetchEvent 触发。我们构造一个自定义响应,如下所示:

  1. 检查在 CacheStorage 中是否找到与请求匹配的内容。如果是这样,那就处理它。
  2. 如果不是,那么从网络获取请求,然后再打开在第一个块中创建的缓存,并使用 Cache.putcache.put(event.request, response.clone()))向其添加请求的副本。
  3. 如果失败(例如,由于网络中断),则返回一个后备响应。

最后,使用 FetchEvent.respondWith 返回自定义响应

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll([
        '/sw-test/',
        '/sw-test/index.html',
        '/sw-test/style.css',
        '/sw-test/app.js',
        '/sw-test/image-list.js',
        '/sw-test/star-wars-logo.jpg',
        '/sw-test/gallery/bountyHunters.jpg',
        '/sw-test/gallery/myLittleVader.jpg',
        '/sw-test/gallery/snowTroopers.jpg'
      ]);
    })
  );
});

self.addEventListener('fetch', function(event) {
  event.respondWith(caches.match(event.request).then(function(response) {
    // caches.match() 始终会解析,但如果成功,响应才有值
    if (response !== undefined) {
      return response;
    } else {
      return fetch(event.request).then(function (response) {
        // 响应只能使用一次。我们需要保存克隆以将一个副本放入缓存并提供第二个副本
        let responseClone = response.clone();

        caches.open('v1').then(function (cache) {
          cache.put(event.request, responseClone);
        });
        return response;
      }).catch(function () {
        return caches.match('/sw-test/gallery/myLittleVader.jpg');
      });
    }
  }));
});

该代码段展示了如何在服务工作线程上下文之外使用 API,并使用 await 运算符来编写更具可读性的代码。

// 尝试从高速缓存中获取数据,如果没有则回退到获取实时数据。
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( '检索缓存的数据' );
      return cachedData;
   }

   console.log( '获取新数据' );

   const cacheStorage = await caches.open( cacheName );
   await cacheStorage.add( url );
   cachedData = await getCachedData( cacheName, url );
   await deleteOldCaches( cacheName );

   return cachedData;
}

// 从缓存中获取数据。
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();
}

// 删除任何旧的缓存,给用户留出磁盘空间。
async function deleteOldCaches( currentCache ) {
   const keys = await caches.keys();

   for ( const key of keys ) {
      const isOurCache = 'myapp-' === key.substr( 0, 6 );

      if ( currentCache === key || ! isOurCache ) {
         continue;
      }

      caches.delete( key );
   }
}

try {
   const data = await getData();
   console.log( { data } );
} catch ( error ) {
   console.error( { error } );
}

规范

规范 状态 备注
Service Workers
CacheStorage 的定义
工作草案 初始定义。

桌面浏览器兼容性

特性ChromeEdgeFirefoxInternet ExplorerOperaSafari
基础支持4012≤18443 不支持2711.1
delete4016443 不支持2711.1
has4016443 不支持2711.1
keys4016443 不支持2711.1
match

54

406

16443 不支持

41

276

11.1
open4016443 不支持2711.1
Secure context required65≤7944 不支持52 支持

移动浏览器兼容性

特性AndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
基础支持40124012 未知44 未知27 支持
delete4040 未知44 未知27 支持
has4040 未知44 未知27 支持
keys4040 未知44 未知27 支持
match

54

406

54

406

未知44 未知

41

276

支持
open4040 未知44 未知27 支持
Secure context required6565 未知44 未知47 支持

1. 从版本 43 开始,可以从 Window 访问。

2. 从版本 43 开始,可以从 WorkerGlobalScope 访问。

3. 在 Firefox 45 和 52 扩展支持版本(ESR)中,服务工作线程(和 Push)已被禁用。

4. 从 Samsung Internet 4.0 开始,可以从 Window 访问。

5. 从 Samsung Internet 4.0 开始,可以从 WorkerGlobalScope 访问。

6. options 参数仅支持 ignoreSearchcacheName

相关链接