方圆网通网站建设公司,对外宣传推广方案,h5开发app,wordpress 上传网站吗前言
目前浏览器的存储机制有很多#xff0c;如#xff1a;indexedDB、localStorage、sessionStorage、File System API、applicationCache 等等#xff0c;那为什么又制定了一套 Cache API 呢#xff1f;对比其他存储机制有什么优势#xff1f;
简介
Cache API 是一套…前言
目前浏览器的存储机制有很多如indexedDB、localStorage、sessionStorage、File System API、applicationCache 等等那为什么又制定了一套 Cache API 呢对比其他存储机制有什么优势
简介
Cache API 是一套搭配 PWA serviceworker 赋能的存储机制来实现请求数据离线功能。与 applicationCache 相似提供了力度极细的存储控制能力内容完全由脚本控制。常在 serviceworker 中搭配 Fetch 使用且同一个 URL 不同 header 可以存储多个 Response。不提供跨域共享且与HTTP缓存完全隔离。
与其他存储机制的区别
Cache API 是异步化的存储方式serviceworker中必须使用异步化存储。Cache API 是以 Requst 做为 keyResponse 做为 value 进行存储的异步化的 IndexDB 基于结构化克隆存储 无法存储流式数据转换成本过高增大内存使用及影响速度。
CacheStorage 方法
CacheStorage 是 Cache 对象存储的接口可以通过两种方式获取
ServiceWorkerGlobalScope.cachesWindow.caches注 必须在 https 环境下才能使用。
下面都是在 ServiceWorkerGlobalScope 环境下。
open
语法
// cachs 是 CacheStorage 实例的只读全局变量
caches.open(cacheName).then(cache {// 处理打开的 cache 实例相关操作
});打开如果没有 cacheName则创建为 cacheName 的 Cache 实例。
返回 Promiseresolve 为Cache 实例。
delete
语法
caches.delete(cacheName).then(boolean {// true: cache 发现并已经删除
});查找匹配 cacheName 的 Cache 对象。找到则删除 Cache 对象并返回一个 resolve 为 true 的 Promise没找到 Cache 对象则返回 false。
keys
语法
caches.keys().then(keyList {//对 keyList 做操作
});返回 Promise。包含 CacheStorage 下所有的 Cache 对象名称字符串的数组。
has
语法
caches.has(cacheName).then(boolean {// true: cacheName 缓存存在
});返回一个 Promise 对象缓存存在时 resolve 的布尔值为 true 否则为 false。
match
语法
caches.match(request[, options]).then(response {// response 操作// 如果未匹配到则 resolve 返回 undefined
});参数
request 要匹配的 Request。可以是 Request 对象或 URL 字符串。
options(可选) 可选。用于控制如何进行匹配操作。
ignoreSearchBooleanfalse。匹配时是否忽略 url 的查询参数。ignoreMethodBooleanfalse。true 时忽略请求方法GET/HEAD匹配。ignoreVaryBooleanfalse。true 时忽略 Vary 头匹配。(什么是Vary)cacheNameString。表示所要搜索的缓存名称。如果不设置则全局搜索查找到第一个立即返回。
Cache 方法
Cache 是 CacheStorage 的存储实现以 Request 做为 key以 Response 做为 value 来进行存储。可以通过 CacheStorage.open(cacheName) 打开 Cache 来进行操作。
Cache 数据生成后将会一直存在修改/删除 需要通过脚本自己去实现。
注 Cache.add/Cache.put/Cache.addAll 只能在 request method 为 GET 的情况下使用。并且相同的 request key 下的 cache在这三个方法下会被覆盖。
put
通过指定的 request 和 response 添加到 cache 中。
response 的 status 可以是任意类型。
语法
cache.put(request, response).then(() {// 将 request/response 键值对添加到cache中
});参数
request你想添加的 Request 。response你想添加匹配 Request 的 Response。
注 request 参数method 只支持 GET否则会出现「TypeError: Request method POST is unsupported」 错误。
delete
删除匹配 request key 的 cache 找到并删除成功 resolve(true)。
语法
cache.delete(request,{options}).then(boolean {// true: 你的 cache 已经删除
});参数
request 请求删除的 Request。 options(可选) 控制删除搜索 key 如何去匹配同 match 方法。
ignoreSearchBooleanfalse。匹配时是否忽略 url 的查询参数。ignoreMethodBooleanfalse。true 时忽略请求方法GET/HEAD匹配。ignoreVaryBooleanfalse。true 时忽略 Vary 头匹配。(什么是Vary)
add
给定 request 参数自动请求获取 response并填入 cache 对象中。 等于 fetch cache.put 。
注 response status 为 opaque 的不能通过 add 方法添加返回 reject。
语法
cache.add(request).then(() {// request 已经添加到 cache
});addAll
和 Cache.add 作用相同参数为 request 的数组。
注 只有在所有 requests 都成功的情况下才能完成 cache 缓存。
语法
cache.addAll(requests[]).then(() {// 所有 requests 都添加到 cache 。
});match
返回匹配 request key 的第一个 cache。
注 即使没有匹配到也将返回 resolve只是值为 undefined。
语法
cache.match(request, {options}).then(response {// 对 response 做一些处理
});参数
request 请求匹配的 Request。 options(可选) 控制搜索 key 如何去匹配同 match 方法。
ignoreSearchBooleanfalse。匹配时是否忽略 url 的查询参数。ignoreMethodBooleanfalse。true 时忽略请求方法GET/HEAD匹配。ignoreVaryBooleanfalse。true 时忽略 Vary 头匹配。(什么是Vary)
matchAll
作用同 Cache.match区别在于 Cache.match 返回匹配的 responses[0]而 Cache.matchAll 返回所有匹配的 responses 数组。
语法
cache.matchAll(request,{options}).then(responses {// 对 responses 数组做一些处理
});参数
request 请求匹配的 Request。 options(可选) 控制搜索 key 如何去匹配同 match 方法。
ignoreSearchBooleanfalse。匹配时是否忽略 url 的查询参数。ignoreMethodBooleanfalse。true 时忽略请求方法GET/HEAD匹配。ignoreVaryBooleanfalse。true 时忽略 Vary 头匹配。(什么是Vary)
keys
返回当前 cache 实例下所有的 key。
注 具有相同URL但不同请求头的请求如果它们的响应头中有 VARY 头部则他们可以被返回。
语法
cache.keys(request,{options}).then(keys {// 对 requests 做一些处理
});参数
request(可选) 如果一个相关 Request key 被指定则返回对应的 Request。 options(可选) 控制搜索 key 如何去匹配同 match 方法。
ignoreSearchBooleanfalse。匹配时是否忽略 url 的查询参数。ignoreMethodBooleanfalse。true 时忽略请求方法GET/HEAD匹配。ignoreVaryBooleanfalse。true 时忽略 Vary 头匹配。(什么是Vary)
调试查看
可以通过 Chrome 的 DevTools进行查看。
Application → Cache → Cache Storage
Cache Storage 中是以 caches.open 创建的 cacheName 的 cache右侧列表中是通过 put/add/addAll 添加的 request key点击可以在下方查看相关的 request 和 response。 缓存空间问题
web 端的离线存储方式有三种分别是
TemporaryPersistentUnlimited
而 Cache 属于 Temporary 类型。Temporary 存储是一种临时存储任何Web应用程序都可以在没有前期配额请求或用户提示的情况下使用但存储的数据可以被浏览器随时删掉占用空间过多时自动清理。可以类比于文件系统的 / tmp 目录。
在 Chrome 和 Opera 中可以使用新的实验性 API 向设备请求持久化存取权限
navigator.storage.persist().then(isGranted {// true : 授权
})各浏览器的离线空间
Chrome 6% of free spaceFirefox 10% of free spaceSafari 50MBIE10 250MBEdge Depenent on volume size
溢出处理策略
Chrome LRU once Chrome runs out of sapceFirefox LRU if the whole disk gets fullSafari No evictionEdge No eviction
实际数据可通过 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 响应后面会讲。
POST 缓存
因 Cache 中的规范指出只能存储 GET 类型的 Request所以想缓存 POST 类型的 Request 怎么办呢
这里建议两种方式
将 Response 进行序列化或者将实际数据提取放到 IndexDB 中进行存储监听 fetch 事件的时候匹配 IndexDB 来查找响应并生成 Response 实例。一些特殊的 POST 请求如内容都是固化好的参数通常不会发生变化并且 URL 中有唯一性的标志则可以在 fetch 中监听到这种特殊 POST 时把其转化为 GET 的 Request 来做为 cache 的 key等 Response 收到后把 POST 的 Response 做为转化出来的 GET key 的 value 来存储即可实现。
opaque 不透明响应缓存
针对 response 的 status 为 0 的 opaque 响应资源也是可以存储到 cache 中的但是并不建议存储。因为响应状态是 0并不能确认资源是否完整及正确缓存下来后在 cache 中也是无法查看其长度大小的并且会导致一些存储问题。 并且突然间 Cache Storage 变成了 10.3MB。 但存储的这个 opaque 状态的响应实际只有几 kb但缓存起来却达到好几 MB 这是什么原因呢
其实这是 Chrome 浏览器层为防止出现安全问题所以把所有 opaque 状态的请求都以这种几 MB 的方式进行填充来保证安全的。
所以针对 opaque 状态的请求建议
不进行 opaque 状态类型的缓存。对 opaque 状态类弄的缓存添加 Access-Control-Allow-Origin 头来实现状态透明。
浏览器兼容性 博客名称王乐平博客 CSDN博客地址http://blog.csdn.net/lecepin 本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。