PWA(Progressive Web App)入门系列:Cache Storage Cache

前言

目前浏览器的存储机制有很多,如: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 做为 key,Response 做为 value 进行存储的,异步化的 IndexDB 基于结构化克隆存储, 无法存储流式数据,转换成本过高,增大内存使用及影响速度。

CacheStorage 方法

CacheStorage 是 Cache 对象存储的接口,可以通过两种方式获取:

ServiceWorkerGlobalScope.cachesWindow.caches

注: 必须在 https 环境下才能使用。

下面都是在 ServiceWorkerGlobalScope 环境下。

open

语法:

// cachs 是 CacheStorage 实例的只读全局变量
caches.open(cacheName).then(cache => {// 处理打开的 cache 实例相关操作
});

打开(如果没有 cacheName,则创建)为 cacheName 的 Cache 实例。

返回 Promise,resolve 为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:(可选) 可选。用于控制如何进行匹配操作。

  • ignoreSearch:Boolean,false。匹配时,是否忽略 url 的查询参数。
  • ignoreMethod:Boolean,false。true 时忽略请求方法(GET/HEAD)匹配。
  • ignoreVary:Boolean,false。true 时忽略 Vary 头匹配。(什么是Vary)
  • cacheName:String。表示所要搜索的缓存名称。如果不设置则全局搜索,查找到第一个,立即返回。

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 方法)。

  • ignoreSearch:Boolean,false。匹配时,是否忽略 url 的查询参数。
  • ignoreMethod:Boolean,false。true 时忽略请求方法(GET/HEAD)匹配。
  • ignoreVary:Boolean,false。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 方法)。

  • ignoreSearch:Boolean,false。匹配时,是否忽略 url 的查询参数。
  • ignoreMethod:Boolean,false。true 时忽略请求方法(GET/HEAD)匹配。
  • ignoreVary:Boolean,false。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 方法)。

  • ignoreSearch:Boolean,false。匹配时,是否忽略 url 的查询参数。
  • ignoreMethod:Boolean,false。true 时忽略请求方法(GET/HEAD)匹配。
  • ignoreVary:Boolean,false。true 时忽略 Vary 头匹配。(什么是Vary)

keys

返回当前 cache 实例下所有的 key。

注: 具有相同URL但不同请求头的请求,如果它们的响应头中有 VARY 头部,则他们可以被返回。

语法:

cache.keys(request,{options}).then(keys => {// 对 requests 做一些处理
});

参数:

request:(可选) 如果一个相关 Request key 被指定,则返回对应的 Request。
options:(可选) 控制搜索 key 如何去匹配(同 match 方法)。

  • ignoreSearch:Boolean,false。匹配时,是否忽略 url 的查询参数。
  • ignoreMethod:Boolean,false。true 时忽略请求方法(GET/HEAD)匹配。
  • ignoreVary:Boolean,false。true 时忽略 Vary 头匹配。(什么是Vary)

调试查看

可以通过 Chrome 的 DevTools进行查看。

Application → Cache → Cache Storage

Cache Storage 中是以 caches.open 创建的 cacheName 的 cache,右侧列表中是通过 put/add/addAll 添加的 request key,点击可以在下方查看相关的 request 和 response。

缓存空间问题

web 端的离线存储方式有三种,分别是:

  • Temporary
  • Persistent
  • Unlimited

而 Cache 属于 Temporary 类型。Temporary 存储是一种临时存储,任何Web应用程序都可以在没有前期配额请求或用户提示的情况下使用,但存储的数据可以被浏览器随时删掉(占用空间过多时,自动清理)。可以类比于文件系统的 / tmp 目录。

在 Chrome 和 Opera 中可以使用新的实验性 API 向设备请求持久化存取权限:

navigator.storage.persist().then(isGranted => {// true : 授权
})

各浏览器的离线空间:

  • Chrome <6% of free space
  • Firefox <10% of free space
  • Safari <50MB
  • IE10 <250MB
  • Edge Depenent on volume size

溢出处理策略:

  • Chrome LRU once Chrome runs out of sapce
  • Firefox LRU if the whole disk gets full
  • Safari No eviction
  • Edge 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 怎么办呢?

这里建议两种方式:

  1. 将 Response 进行序列化,或者将实际数据提取,放到 IndexDB 中进行存储,监听 fetch 事件的时候,匹配 IndexDB 来查找响应,并生成 Response 实例。
  2. 一些特殊的 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 国际许可协议进行许可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401647.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「浏览器插件」无广告国内视频平台直接播放插件

前段时间发现一些比较不错的解析国内视频平台的一些 API 接口&#xff0c;很早之前基于这些接口做过一个 Android 端的播放软件&#xff0c;但为了更方便使用吧&#xff0c;于是做了一个 Chrome 的浏览器插件&#xff0c;解析接口也是在线更新的&#xff0c;所以用起来会比较方…

kafka性能测试(转)KAFKA 0.8 PRODUCER PERFORMANCE

来自:http://blog.liveramp.com/2013/04/08/kafka-0-8-producer-performance-2/ At LiveRamp, we constantly face scaling challenges as the volume of data that our infrastructure must deal with continues to grow. One such challenge involves the logging system. At…

Workbox-Window v4.x 中文版

Workbox 目前发了一个大版本&#xff0c;从 v3.x 到了 v4.x&#xff0c;变化有挺大的&#xff0c;下面是在 window 环境下的模块。 什么是 workbox-window? workbox-window 包是一组模块&#xff0c;用于在 window 上下文中运行&#xff0c;也就是说&#xff0c;在你的网页内…

媒体播放器三大底层架构

2019独角兽企业重金招聘Python工程师标准>>> 媒体播放工具&#xff0c;这里主要指视频播放&#xff0c;因为要面临庞大的兼容性和纷繁复杂的算法&#xff0c;从架构上看&#xff0c;能脱颖而出的体系屈指可数。大体来说业界主要有3大架构&#xff1a;MPC、MPlayer和…

PWA 可用性检测工具

针对移动端或者 PC 端浏览器是否对 PWA 可用的问题上&#xff0c;做了一个简单的站点&#xff0c;来实现上述问题的方便检测。让开发者较快的了解终端浏览器的特性支持度。 使用 工具地址&#xff1a;https://lecepin.gitee.io/detect-sw/ 地址二维码&#xff1a; 检测 可…

PWA 应用列表及常用工具

引言 在做 PWA 的过程中自己写了一些相关的应用和工具&#xff0c;在这里整合下&#xff0c;方便记录及查找使用。 应用列表 PWA 支持检测工具番茄钟二维码生成新闻应用身体数据统计应用支付宝集福应用田英章书法字典应用抖音无水印下载应用很好用的备忘录精神氮泵 PWA 支持检…

Struts2中访问HttpServletRequest和HttpSession

2019独角兽企业重金招聘Python工程师标准>>> 关键字: struts2 httpservletrequest httpsession 在没有使用Struts2之前,都习惯使用HttpServletRequest和HttpSession对象来操作相关参数,下面介绍一下在Struts2中访问隐藏的HttpServletRequest和HttpSession的两种方法…

web前端长度单位详解(px、em、rem、%、vw/vh、vmin/vmax、vm、calc())

基础理论1&#xff09;简介2&#xff09;绝对长度3&#xff09;相对长度4&#xff09;经验之谈1&#xff09;简介 在前端开发中&#xff0c;会遇到各种不同类型的长度单位&#xff0c;比如px,em,rem等。 而整体的长度单位分为两大类&#xff1a;相对长度 和 绝对长度。 2&…

PWA(Progressive Web App)入门系列:Fetch Request Headers Response Body

前言 在 WEB 中&#xff0c;对于网络请求一直使用的是 XMLHttpRequest API 来处理&#xff0c;XMLHttpRequest 也很强大&#xff0c;传统的 Ajax 也是基于此 API 的。那么为什么 W3C 标准中又加入了类似功能的 Fetch API 呢&#xff1f;他有何优势。 Fetch 什么是 Fetch Fet…

CSS3开发总结(圆角、盒阴影、边界图片)

CSS3开发总结&#xff08;圆角&#xff09; 12/100 发布文章 qq_41913971 CSS31&#xff09;圆角 border-radius2&#xff09;盒阴影 box-shadow3&#xff09;边界图片 border-image-source1&#xff09;圆角 border-radius border-radius属性&#xff0c;复合属性。一个最多可…

深入理解Android的startservice和bindservice

一、首先&#xff0c;让我们确认下什么是service&#xff1f; service就是android系统中的服务&#xff0c;它有这么几个特点&#xff1a;它无法与用户直接进行交互、它必须由用户或者其他程序显式的启动、它的优先级比较高&#xff0c; 它比处于前台的应用优先级低&am…

PWA(Progressive Web App)入门系列:Notification

前言 在很多场景下&#xff0c;需要一种通知的交互方式来提醒用户&#xff0c;传统方式下可以在页面实现一个 Dialog&#xff0c;或通过修改网页的 title 来实现消息的通知。然而传统的实现存在着一定的不足&#xff0c;在网页最小化的情况下&#xff0c;无法查看任何通知&…

PWA(Progressive Web App)入门系列:Push

前言 很多时候&#xff0c;原生应用会通过一些消息推送来唤起用户的关注&#xff0c;增加驻留率。网页该怎么做呢&#xff1f;有没有类似原生应用的推送机制&#xff1f;推送功能又能玩出什么花样呢&#xff1f; Push API Push API 给与了 Web 应用程序接收从服务器发出的推送…

Dom学习笔记

DOM document object model 文档 对象 模型 文档&#xff1a;html页面 文档对象&#xff1a;页面中的元素 文档对象模型: 文档对象模型是w3c 为了能够让js去操作页面中的元素&#xff0c;定义的一套标准 DOM会把当前文档看作一棵树 树种的每一个元素就是文档树 的一个节点 同…

PWA(Progressive Web App)入门系列:消息通讯

前言 serviceWorker 的能力决定它要处理的事情&#xff0c;网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理&#xff0c;这里就要页面层和 serviceWorker 层进行交互来实现消息通讯。 下面就说一下两个环境下的消息通讯。 窗口向 serviceWorker 通讯 这里列举出窗…

查看Linux上程序或进程用到的库

为什么80%的码农都做不了架构师&#xff1f;>>> ldd /path/to/program 要找出某个特定可执行依赖的库&#xff0c;可以使用ldd命令。这个命令调用动态链接器去找到程序的库文件依赖关系。 objdump -p /path/to/program | grep NEEDED 注意&#xff01;并不推荐为任…

超方便的 IndexDB 库

前言 做为 Web 浏览器层的本地存储&#xff0c;IndexDB 做为一个很好的选择&#xff0c;几乎可以存储任意类型的数据&#xff0c;且是异步的。但是正常使用方式下需要在监听各种事件来处理结果&#xff0c;不是很方便&#xff0c;下面就对这一层进行了包装&#xff0c;使用方便…

BP网络识别26个英文字母matlab

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;字母识别 获取完整源码源工程文件 一、 设计思想 字符识别在现代日常生活的应用越来越广泛&#xff0c;比如车辆牌照自动识别系统&#xff0c;手写识别系统&#xff0c;办公自动化等等。本文采用BP网络对26个英文字母进行…

PWA(Progressive Web App)入门系列:Sync 后台同步

前言 当我们在一些地下停车场&#xff0c;或者在火车上、电梯等无法避免的信号不稳定的场所&#xff0c;使用网站应用处理一些表单操作或者上传数据的操作时&#xff0c;面临的将是网络连接错误的响应&#xff0c;使用户的操作白费。 而此刻 PWA 的 Sync API 就很好的解决了这…

PWA(Progressive Web App)入门系列:安装 Web 应用

前言 在传统的 Web 应用中&#xff0c;通常只能通过在浏览器的地址栏里输入相应的网址才能进行访问&#xff0c;或者把网页地址创建到桌面上通过点击&#xff0c;然后在浏览器里打开。 传统模式下&#xff0c;图标、启动画面、主题色、视图模式、屏幕方向等等都无法去自定义和…