客戶端存儲(chǔ)CacheStorage

緩存數(shù)據(jù)的大小

  • 每個(gè)瀏覽器都硬性限制了一個(gè)域下緩存數(shù)據(jù)的大小。

  • 瀏覽器盡其所能去管理磁盤空間,但它有可能刪除一個(gè)域下的緩存數(shù)據(jù)。

  • 瀏覽器要么自動(dòng)刪除特定域的全部緩存,要么全部保留。

StorageEstimate

  • 提供對(duì)你的域名或Web app的數(shù)據(jù)存儲(chǔ)空間總量和已用量的估計(jì)值。

  • StorageEstimate.quota: 用戶設(shè)備為你的域名或Web app預(yù)留的存儲(chǔ)空間總大小,且該大小為估計(jì)值.雖然實(shí)際上可能有比這更多的存儲(chǔ)空間,但這時(shí)你不應(yīng)使用那多余的部分。原始的單位是byte.

  • StorageEstimate.usage: 你的域名或Web app已經(jīng)使用的存儲(chǔ)空間大小,且該大小為估計(jì)值.剩余可用空間請(qǐng)綜合quota屬性計(jì)算。原始的單位是byte。

if(navigator.storage && navigator.storage.estimate) {
  navigator.storage.estimate().then(estimate => {
    // 原始的單位是byte. 轉(zhuǎn)成MB
    const ut = 1024 * 1024;
    return ({
      total: estimate.quota / ut,
      usage: estimate.usage / ut
    });
  });
};

一個(gè)域可以有多個(gè)命名 Cache 對(duì)象

  • 除非明確地更新緩存,否則緩存將不會(huì)被更新。

  • 除非刪除,否則緩存數(shù)據(jù)不會(huì)過期。

CacheStorage Api

1. CacheStorage.open(cacheName)

  • params [String] cacheName
  • 接口的 open() 方法返回一個(gè)resolve為匹配 cacheName 的Cache 對(duì)象的 Promise。
  • 如果指定的 Cache 不存在,則使用該 cacheName 創(chuàng)建一個(gè)新的cache,并返回一個(gè)resolve為該新 Cache 對(duì)象的Promise
  // 示例
  const cacheName = 'test-cache-name'
  caches.open(cacheName).then(cache => {
    // cache 對(duì)象
    console.log('cache.....', cache);
  })

2. CacheStorage.match(request, options)

  • 檢查給定的Request 對(duì)象或url字符串是否是一個(gè)已存儲(chǔ)的 Response 對(duì)象的key. 這個(gè)方法針對(duì) Response 返回一個(gè) Promise ,如果沒有匹配則返回 undefined 。

  • 提示: caches.match() 是一個(gè)便捷方法。其作用等同于在每個(gè)緩存上調(diào)用 cache.match() 方法 (按照caches.keys()返回的順序) 直到返回Response 對(duì)象。

  • Request: 想要匹配的 Request。這個(gè)參數(shù)可以是 Request 對(duì)象或 URL 字符串。

  // 示例 url
  const notExistUrl = '/api'
  caches.match(notExistUrl).then(res => {
    console.log(res) // undefined
  })
  const existUrl = '/index.js'
  caches.match(existUrl).then(res => {
    console.log(res) // Response
  })
  // Request 對(duì)象
  const req = new Request('http://localhost:8008/api/ws', {
    method: 'get',
  })
  caches.match(req).then(res => {
    return res.json()
  }).then(r => {
    console.log(r); // {a: 1, b: 2}
  })
  • options: [可選] 這個(gè)對(duì)象中的屬性控制在匹配操作中如何進(jìn)行匹配選擇。可選擇參數(shù)如下:

ignoreSearch: [Boolean] 指定匹配過程是否應(yīng)該忽略u(píng)rl中查詢參數(shù)。舉個(gè)例子,如果該參數(shù)設(shè)置為true, 那么 ?value=bar 作為 http://foo.com/?value=bar 中的查詢參數(shù)將會(huì)在匹配過程中被忽略。該參數(shù)默認(rèn) false。

  const existUrlAndQuery = '/index.js?a=1'
  caches.match(existUrlAndQuery).then(res=>
  {
    console.log(res) // undefined
  })
  caches.match(existUrlAndQuery, {
    ignoreSearch: true
  }).then(res => {
    console.log(res) // Response
  })

ignoreMethod: [Boolean] 當(dāng)被設(shè)置為 true 時(shí),將會(huì)阻止在匹配操作中對(duì) Request請(qǐng)求的 http 方式的驗(yàn)證 (通常只允許 GET 和 HEAD 兩種請(qǐng)求方式)。該參數(shù)默認(rèn)為 false。

// POST請(qǐng)求不允許緩存。

// 報(bào)錯(cuò) cache.js:13 Uncaught (in promise) TypeError: Failed to execute 'add' on 'Cache': Add/AddAll only supports the GET request method.

  const req = new Request(
    'http://localhost:8008/api/ws', {
      method: 'head', // post, get, head都一樣被忽略
      mode: 'cors',
    })
  caches.match(req, {
    cacheName: 'test-cache-name',
    ignoreMethod: true
  }).then(res => {
    return res.json()
  }).then(r => {
    console.log(r); // {a: 1, b: 2}
  })

ignoreVary: [Boolean] 當(dāng)該字段被設(shè)置為 true, 告知在匹配操作中忽略對(duì)VARY頭信息的匹配。換句話說,當(dāng)請(qǐng)求 URL 匹配上,你將獲取匹配的 Response 對(duì)象,無論請(qǐng)求的 VARY 頭存在或者沒有。該參數(shù)默認(rèn)為 false。

  // 沒理解
  const req = new Request('http://localhost:8008/api/ws', {
    method: 'get',
    mode: 'cors',
    vary: 'User-Agent'
  })
  caches.match(req, {
    cacheName: 'test-cache-name',
    ignoreVary: false
  }).then(res => {
    return res.json()
  }).then(r => {
    console.log(r); // {a: 1, b: 2}
  })

cacheName: [DOMString] 表示所要搜索的緩存名稱.

[圖片上傳失敗...(image-d67305-1601447981344)]
[圖片上傳失敗...(image-28bf4e-1601447981345)]

// 指定cacheName
const cacheName = 'test-cache-name';
caches.match('/cache.js', {
  cacheName
}).then(res => {
  return res.text()
}).then(r => {
  console.log(r);
})

3. CacheStorage.has(cacheName)

  • 對(duì)象的 has()方法返回一個(gè)Promise對(duì)象,當(dāng)Cache對(duì)象有cacheName時(shí)被處理為true 。
  // 存在 cacheName
  caches.has('test-cache-name').then((res) => {
    console.log(res) // true
  });
  // 不存在 cacheName
  caches.has('test-cache-name-not').then((res) => {
    console.log(res) // false
  });

4. CacheStorage.delete(cacheName)

  • delete() 方法查找匹配 cacheName的Cache對(duì)象,如果找到,則刪除Cache對(duì)象并返回一個(gè)resolve為true的Promise.如果未找到Cache對(duì)象,則返回false.
  const testDeleteCacheName = 'test-delete-cache-name'
  caches.open(testDeleteCacheName).then(r => {
    // 刪除test-delete-cache-name
    caches.delete(testDeleteCacheName).then((res) => {
      console.log(res); // true
    });
    // 刪除不存在的test-cache-name-not
    caches.delete('test-cache-name-not').then((res) => {
      console.log(res); // false
    });
  })

5. CacheStorage.keys()

  • keys() 方法返回一個(gè) Promise對(duì)象,它使用一個(gè)數(shù)組resolve,該數(shù)組包含 CacheStorage 對(duì)象按創(chuàng)建順序跟蹤的所有命名Cache對(duì)象對(duì)應(yīng)的字符串。使用此方法迭代所有Cache對(duì)象。
  // 按創(chuàng)建順序
  caches.keys().then(res => {
    console.log(res);
    //我本地的["my-test-cache-v1", "workbox-runtime-http://127.0.0.1:5500/", "test-cache-name"]
  })

Cache Api

  • Cache是CacheStorage某一個(gè)命名的caheName的對(duì)象,如下代碼:
  // 示例
  const cacheName = 'test-cache-name'
  caches.open(cacheName).then(cache => {
    // cache對(duì)象就是cacheName為'test-cache-name'的cache對(duì)象
    console.log('cache.....', cache);
  })

1. cache.match(request, options)

  • match() 方法, 返回一個(gè) Promise 解析為(resolve to)與 Cache 對(duì)象中的第一個(gè)匹配請(qǐng)求相關(guān)聯(lián)的Response 。如果沒有找到匹配,Promise 解析為 undefined。
  • 其他參數(shù)同CacheStorage.match()
  // 存在
  const req1 = new Request('http://localhost:8008/api/ws', {
    method: 'get',
    mode: 'cors',
  })
  const notExistUrl = 'not-exist-url'
  caches.open('test-cache-name').then(cache => {
    cache.match(req1,).then(r => {
      console.log(r); // Response
    })
    cache.match(notExistUrl,).then(r => {
      console.log(r); // undefined
    })
  })

2. cache.matchAll(request, options)

  • matchAll() 方法返回一個(gè) Promise ,其 resolve 為 Cache 對(duì)象中所有匹配請(qǐng)求的數(shù)組。
  • Cache 中你嘗試查找的The Request . 如果忽略這一參數(shù),你將獲取到cache中所有 response 的副本。
  cache.matchAll().then(res => {
    console.log(res) // [Response, Response, Response]
  })

3. cache.add(request)

  • add()方法接受一個(gè)URL作為參數(shù),請(qǐng)求參數(shù)指定的URL,并將返回的response對(duì)象添加到給定的cache中.
  • 返回一個(gè)promise,但是res為undefined
  // cache.add方法等同于下面,默認(rèn)發(fā)起一個(gè)fetch請(qǐng)求
  fetch(url).then(function (response) {
    if (!response.ok) {
      throw new TypeError('bad response status');
    }
    return cache.put(url, response);
  })
  const req = new Request('http://localhost:8008/v3/test-6', {
    method: 'get'
  })
  caches.open('test-cache-name').then(cache => {
    cache.add('style.css').then(res => {
      console.log('style.css....', res);
    })
    // 無需發(fā)起fetch請(qǐng)求,默認(rèn)發(fā)起,將請(qǐng)求結(jié)果緩存。
    cache.add(req).then(res => {
      console.log('add....req....', res);
    })
  })

4. cache.addAll(requests)

  • addAll() 方法接受一個(gè)URL數(shù)組,檢索它們,并將生成的response對(duì)象添加到給定的緩存中。 在檢索期間創(chuàng)建的request對(duì)象成為存儲(chǔ)的response操作的key。
  const req1 = new Request('http://localhost:8008/v3/test-1', {
    method: 'get'
  })
  const req2 = new Request('http://localhost:8008/v3/test-2', {
    method: 'get'
  })
  const req3 = new Request('http://localhost:8008/v3/test-3', {
    method: 'get'
  })
  caches.open('test-cache-name').then(cache => {
    cache.addAll([
      req1,
      req2,
      req3,
      'style.css'
    ]).then(res => {
      console.log('add....req....', res);
    })
  })

5. cache.delete(request,{options})

  • delete() 方法查詢r(jià)equest為key的 Cache 條目,如果找到,則刪除該 Cache 條目并返回resolve為true的 Promise 。 如果沒有找到,則返回resolve為false的 Promise 。

  • options參數(shù)同match參數(shù)用法一致

ignoreSearch: 一個(gè) Boolean 值,指定匹配進(jìn)程中是否忽略u(píng)rl中的查詢字符串。如果設(shè)置為true,http://foo.com/?value=bar 中的 ?value=bar 部分在執(zhí)行匹配時(shí)會(huì)被忽略。默認(rèn)為false。
ignoreMethod: 一個(gè) Boolean 值,當(dāng)設(shè)置為true時(shí),將阻止匹配操作驗(yàn)證{domxref("Request")}} HTTP方法(通常只允許GET和HEAD)。默認(rèn)為false。
ignoreVary: [Boolean] 當(dāng)該字段被設(shè)置為 true, 告知在匹配操作中忽略對(duì)VARY頭信息的匹配。換句話說,當(dāng)請(qǐng)求 URL 匹配上,你將獲取匹配的 Response 對(duì)象,無論請(qǐng)求的 VARY 頭存在或者沒有。該參數(shù)默認(rèn)為 false。
cacheName: [DOMString] 表示所要搜索的緩存名稱.

  const req1 = new Request('http://localhost:8008/v3/test-1', {
    method: 'get'
  })
  caches.open('test-cache-name').then(cache => {
    cache.delete(req1).then(res => {
      console.log(res); // true
    })
  })

6. cache.keys(request,{options})

  • keys() 方法返回一個(gè) Promise ,這個(gè) Promise 將解析為一個(gè)Cache 鍵的數(shù)組。請(qǐng)求將以它們被插入的順序返回。

  • request如果一個(gè)相關(guān)鍵被指定,則返對(duì)應(yīng)的 Request 。

  • options參數(shù)同macth用法

  const req3 = new Request('http://localhost:8008/v3/test-3', {
    method: 'get'
  })
  caches.open('test-cache-name').then(cache => {
    cache.keys().then(res => {
      console.log(res); // [Request, Request, Request]
    })
    cache.keys().then(res => {
      console.log(res); // [Request, Request, Request]
    })
    cache.keys(req3).then(res => {
      console.log('req3.....', res); // 返回對(duì)應(yīng)的key req3的[Request]
    })
  })

7. cache.put(request, response)

  • put() 方法 允許將鍵/值對(duì)添加到當(dāng)前的 Cache 對(duì)象中.
  • 注意: put() 將覆蓋先前存儲(chǔ)在匹配請(qǐng)求的cache中的任何鍵/值對(duì)。
  • 注意: Cache.add/Cache.addAll 不會(huì)緩存 Response.status 值不在200范圍內(nèi)的響應(yīng),而 Cache.put 允許你存儲(chǔ)任何請(qǐng)求/響應(yīng)對(duì)。因此,Cache.add/Cache.addAll 不能用于不透明的響應(yīng),而 Cache.put 可以。
  • 注意: 當(dāng)響應(yīng)主體完全寫入磁盤時(shí),初始Cache執(zhí)行 (在 Blink 和 Gecko中) resolve Cache.add、Cache.addAll 和 Cache.put promise. 更新的規(guī)范版本中聲明:即使響應(yīng)主體仍在流式傳輸,一旦條目被記錄到數(shù)據(jù)庫(kù)中,瀏覽器就可以 resolve promise.
// url
const url = 'style.css';
fetch(url).then(function(response) {
  if (!response.ok) {
    throw new TypeError('Bad response status');
  }
  return cache.put(url, response);
})
// Request
const req1 = new Request('http://localhost:8008/v3/test-1', {
  method: 'get'
})
fetch(req1).then(res => {
  cache.put(req1, res)
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。