目前浏览器的存储机制有不少,如: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 中也是没法查看其长度大小的,而且会致使一些存储问题。
其实这是 Chrome 浏览器层为防止出现安全问题,因此把全部 opaque 状态的请求都以这种几 MB 的方式进行填充来保证安全的。
因此针对 opaque 状态的请求,建议:
Access-Control-Allow-Origin
头来实现状态透明。博客名称:王乐平博客
CSDN博客地址:blog.csdn.net/lecepin