目前瀏覽器的存儲機制有不少,如:indexedDB、localStorage、sessionStorage、File System API、applicationCache 等等,那爲何又制定了一套 Cache API 呢?對比其餘存儲機制有什麼優點?web
Cache API 是一套搭配 PWA serviceworker 賦能的存儲機制,來實現請求數據離線功能。與 applicationCache 類似,提供了力度極細的存儲控制能力,內容徹底由腳本控制。常在 serviceworker 中搭配 Fetch 使用,且同一個 URL 不一樣 header 能夠存儲多個 Response。不提供跨域共享,且與HTTP緩存徹底隔離。api
與其餘存儲機制的區別:跨域
CacheStorage 是 Cache 對象存儲的接口,能夠經過兩種方式獲取:數組
ServiceWorkerGlobalScope.caches
Window.caches
複製代碼
注: 必須在 https 環境下才能使用。瀏覽器
下面都是在 ServiceWorkerGlobalScope 環境下。緩存
語法:安全
// cachs 是 CacheStorage 實例的只讀全局變量
caches.open(cacheName).then(cache => {
// 處理打開的 cache 實例相關操做
});
複製代碼
打開(若是沒有 cacheName,則建立)爲 cacheName 的 Cache 實例。session
返回 Promise,resolve 爲Cache 實例。app
語法:cors
caches.delete(cacheName).then(boolean => {
// true: cache 發現並已經刪除
});
複製代碼
查找匹配 cacheName 的 Cache 對象。找到則刪除 Cache 對象並返回一個 resolve 爲 true 的 Promise;沒找到 Cache 對象,則返回 false。
語法:
caches.keys().then(keyList => {
//對 keyList 作操做
});
複製代碼
返回 Promise。包含 CacheStorage 下全部的 Cache 對象名稱字符串的數組。
語法:
caches.has(cacheName).then(boolean => {
// true: cacheName 緩存存在
});
複製代碼
返回一個 Promise 對象,緩存存在時 resolve 的布爾值爲 true 不然爲 false。
語法:
caches.match(request[, options]).then(response => {
// response 操做
// 若是未匹配到,則 resolve 返回 undefined
});
複製代碼
參數:
request: 要匹配的 Request。能夠是 Request 對象或 URL 字符串。
options:(可選) 可選。用於控制如何進行匹配操做。
Cache 是 CacheStorage 的存儲實現,以 Request 作爲 key,以 Response 作爲 value 來進行存儲。能夠經過 CacheStorage.open(cacheName)
打開 Cache 來進行操做。
Cache 數據生成後,將會一直存在,修改/刪除 須要經過腳本本身去實現。
注: Cache.add/Cache.put/Cache.addAll
只能在 request method 爲 GET 的狀況下使用。而且相同的 request key 下的 cache,在這三個方法下會被覆蓋。
經過指定的 request 和 response 添加到 cache 中。
response 的 status 能夠是任意類型。
語法:
cache.put(request, response).then(() => {
// 將 request/response 鍵值對添加到cache中
});
複製代碼
參數:
注: request 參數,method 只支持 GET,不然會出現「TypeError: Request method POST
is unsupported」 錯誤。
刪除匹配 request key 的 cache ,找到並刪除成功 resolve(true)。
語法:
cache.delete(request,{options}).then(boolean => {
// true: 你的 cache 已經刪除
});
複製代碼
參數:
request: 請求刪除的 Request。 options:(可選) 控制刪除搜索 key 如何去匹配(同 match 方法)。
給定 request 參數,自動請求獲取 response,並填入 cache 對象中。 等於 fetch + cache.put
。
注: response status 爲 opaque 的不能經過 add 方法添加,返回 reject。
語法:
cache.add(request).then(() => {
// request 已經添加到 cache
});
複製代碼
和 Cache.add 做用相同,參數爲 request 的數組。
注: 只有在全部 requests 都成功的狀況下,才能完成 cache 緩存。
語法:
cache.addAll(requests[]).then(() => {
// 全部 requests 都添加到 cache 。
});
複製代碼
返回匹配 request key 的第一個 cache。
注: 即便沒有匹配到,也將返回 resolve,只是值爲 undefined。
語法:
cache.match(request, {options}).then(response => {
// 對 response 作一些處理
});
複製代碼
參數:
request: 請求匹配的 Request。 options:(可選) 控制搜索 key 如何去匹配(同 match 方法)。
做用同 Cache.match,區別在於 Cache.match 返回匹配的 responses[0],而 Cache.matchAll 返回全部匹配的 responses 數組。
語法:
cache.matchAll(request,{options}).then(responses => {
// 對 responses 數組作一些處理
});
複製代碼
參數:
request: 請求匹配的 Request。 options:(可選) 控制搜索 key 如何去匹配(同 match 方法)。
返回當前 cache 實例下全部的 key。
注: 具備相同URL但不一樣請求頭的請求,若是它們的響應頭中有 VARY 頭部,則他們能夠被返回。
語法:
cache.keys(request,{options}).then(keys => {
// 對 requests 作一些處理
});
複製代碼
參數:
request:(可選) 若是一個相關 Request key 被指定,則返回對應的 Request。 options:(可選) 控制搜索 key 如何去匹配(同 match 方法)。
能夠經過 Chrome 的 DevTools進行查看。
Application → Cache → Cache Storage
Cache Storage 中是以 caches.open 建立的 cacheName 的 cache,右側列表中是經過 put/add/addAll 添加的 request key,點擊能夠在下方查看相關的 request 和 response。
web 端的離線存儲方式有三種,分別是:
而 Cache 屬於 Temporary 類型。Temporary 存儲是一種臨時存儲,任何Web應用程序均可以在沒有前期配額請求或用戶提示的狀況下使用,但存儲的數據能夠被瀏覽器隨時刪掉(佔用空間過多時,自動清理)。能夠類比於文件系統的 / tmp 目錄。
在 Chrome 和 Opera 中可使用新的實驗性 API 向設備請求持久化存取權限:
navigator.storage.persist().then(isGranted => {
// true : 受權
})
複製代碼
各瀏覽器的離線空間:
溢出處理策略:
實際數據可經過 Quota Management API 來查看。
對於跨域緩存,跨域的資源須要開啓 Access-Control-Allow-Origin
頭部,而且 Request 的 mode 須要設置爲 cors。
const req = new Request("https://cross.com", { mode: "cors" });
fetch(req).then(response => {
caches.open("cacheName").then(cache => {
cache.put(req, res);
});
});
複製代碼
若是跨域資源沒有開啓 Access-Control-Allow-Origin
頭部,則須要把 mode 設置爲 no-cors,但會致使 response 的 status 爲 0 的 opaque 響應,後面會講。
因 Cache 中的規範指出只能存儲 GET 類型的 Request,因此想緩存 POST 類型的 Request 怎麼辦呢?
這裏建議兩種方式:
針對 response 的 status 爲 0 的 opaque 響應資源,也是能夠存儲到 cache 中的,可是並不建議存儲。由於響應狀態是 0,並不能確認資源是否完整及正確,緩存下來後,在 cache 中也是沒法查看其長度大小的,而且會致使一些存儲問題。
而且,忽然間 Cache Storage 變成了 10.3MB。 但存儲的這個 opaque 狀態的響應實際只有幾 kb,但緩存起來卻達到好幾 MB 這是什麼緣由呢?其實這是 Chrome 瀏覽器層爲防止出現安全問題,因此把全部 opaque 狀態的請求都以這種幾 MB 的方式進行填充來保證安全的。
因此針對 opaque 狀態的請求,建議:
Access-Control-Allow-Origin
頭來實現狀態透明。博客名稱:王樂平博客
CSDN博客地址:blog.csdn.net/lecepin