Storage API简介和存储限制与逐出策略
简介
对于现代浏览器来说,为了提升效率和处理更加复杂的客户端操作,通常都需要将数据存储在客户端,也就是本地磁盘上。那么这个存储有没有什么限制?如果数据存满了之后,如何进行数据的淘汰和置换?
一起来看看吧。
常用的客户端存储方式
客户的存储方式都有哪些呢?
我们看一下比较常用的几种方式:
- IndexedDB
- asm.js caching
- Cache API
- Cookies
- web storage
当然还有其他的客户端存储类型,比如AppCache(已经被废弃),File System API(非标准的API)等。
data storage的类型
通常来说,data storage有两种方式,一种是永久性的,这种情况下通常数据会存储比较长的时间,除非用户选择清除(比如清除浏览器缓存),否则数据将会永久保存。
一种是临时存储,这种情况下,数据会存储有限的时间。数据存储的容量是有限的,在有限的数据容量空间,我们需要一些特定的数据逐出算法来保证有效的数据不会被覆盖。
逐出策略
在使用临时存储模式时,我们通常使用的逐出策略是LRU。
当到达存储的限额的时候,将会查找所有当前未使用的origin,然后根据最后访问时间对他们进行排序。然后删除最近最少使用的origin信息。
Storage API
为了统一和规范这些客户端的操作API,于是引入了Storage API,通过Storage API我们可以查看可用存储空间大小,已使用的空间大小,甚至可以控制在用户数据清除的时候是否需要提醒用户。
注意Storage API只适用于HTTPS的情况,并且只是部分浏览器支持。
为了对不同源的数据进行管理,引入了storage units(也叫做box)的概念,对于每一个源来说,都有一个storage units(Box)。
不同的storage units里面可以存储不同类型的数据。
上图中Origin 1中既有Web Storage,也有IndexedDB的存储,因为并没有达到Storage的最大值,所以还留有一定的空余空间。
Origin 2中还没有开始存储任何数据,所以都是空的。
Origin 3中被indexedDB存满了,没有任何空余空间。
为了方便管理box有两种模式,一种叫best-effort,一种叫persistent。
best-effort模式是指浏览器会尽最大努力去保留数据,但是当存储空间用完的时候,浏览器并不会提醒用户可能对存储空间的清理操作。
persistent模式将会尽可能长时间的保存用户的数据,如果同时有best-effort和persistent模式的话,当存储空间不足的时候,将会首先清除best-effort box。如果一定要清除persistent box,将会通知相应的用户。
Storage API指的就是StorageManager,它有三个非常重要的方法estimate,persist和persisted,我们看下他们的浏览器兼容性:
基本上,现代浏览器都支持StorageManager和它的三个方法。
下面我们分别来看一下他们的使用。
StorageManager是一个接口,用来管理存储的权限和评估可用的空间。我们可以通过navigator.storage 或者WorkerNavigator.storage 来获取到StorageManager。
我们看一下StorageManger的定义:
interface StorageManager {
estimate(): Promise<StorageEstimate>;
persist(): Promise<boolean>;
persisted(): Promise<boolean>;
}
estimate
estimate方法返回一个Promise,Promise中包含一个StorageEstimate对象,表示空间的使用情况和限额。
navigator.storage.estimate().then(estimate => {
// estimate.quota is the estimated quota
// estimate.usage is the estimated number of bytes used
});
我们使用estimate来查看是否有住够的空间进行应用数据的存储:
function retrieveNextChunk(nextChunkInfo) {
return navigator.storage.estimate().then(info => {
if (info.quota - info.usage > nextChunkInfo.size) {
return fetch(nextChunkInfo.url);
} else {
throw new Error("insufficient space to store next chunk");
}
}).then( /* … */ );
}
上面是一个estimate的使用。
persist
persist方法返回一个Promise,true表示user agent已被授权,并且box mode= persistent模式。
我们看一下persist 的使用:
if (navigator.storage && navigator.storage.persist)
navigator.storage.persist().then(function(persistent) {
if (persistent)
console.log("Storage will not be cleared except by explicit user action");
else
console.log("Storage may be cleared by the UA under storage pressure.");
});
persisted
persisted方法返回一个Promise,true表示box mode= persistent模式。
我们看一个persisted的例子:
if (navigator.storage && navigator.storage.persist)
navigator.storage.persisted().then(function(persistent) {
if (persistent)
console.log("Storage will not be cleared except by explicit user action");
else
console.log("Storage may be cleared by the UA under storage pressure.");
});
综合使用
之前讲到了,如果是persistent模式,数据的清理需要通知用户,下面我们看一下这个判断该怎么写:
Promise.all([
navigator.storage.persisted(),
navigator.permissions.query({name: "persistent-storage"})
]).then(([persisted, permission]) => {
if (!persisted && permission.status == "granted") {
navigator.storage.persist().then( /* … */ );
} else if (!persisted && permission.status == "prompt") {
showPersistentStorageExplanation();
}
});
上面的例子,我们还使用到了Permissions API。通过Permissions API,我们来判断用户所拥有的权限。
Permissions API还是一个比较新的API,只有在Chrome 44和Firefox 43之后才支持。
我们可以通过navigator.permissions来获取到Permissions API。
可以通过Permissions.query()来判断是否具有相应的权限。
Permissions.query将会返回一个PermissionStatus对象,这个对象代表了三个状态:granted,prompt和denied。
我们看一个判断权限的应用:
function handlePermission() {
navigator.permissions.query({name:'geolocation'}).then(function(result) {
if (result.state == 'granted') {
report(result.state);
geoBtn.style.display = 'none';
} else if (result.state == 'prompt') {
report(result.state);
geoBtn.style.display = 'none';
navigator.geolocation.getCurrentPosition(revealPosition,positionDenied,geoSettings);
} else if (result.state == 'denied') {
report(result.state);
geoBtn.style.display = 'inline';
}
result.onchange = function() {
report(result.state);
}
});
}
function report(state) {
console.log('Permission ' + state);
}
handlePermission();
除了Query,我们还可以使用revoke来取消授权。
function revokePermission() {
navigator.permissions.revoke({name:'geolocation'}).then(function(result) {
report(result.state);
});
总结
Storage API是为了统一客户端存储标准所制定的API。还在不断的完善之中。感兴趣的朋友可以多多关注它的进展。
本文作者:flydean程序那些事
本文链接:http://www.flydean.com/storage-api-limit/
本文来源:flydean的博客
欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
Storage API简介和存储限制与逐出策略的更多相关文章
- 学习笔记:Web Storage API
Web Storage API 提供了存储机制,通过该机制,浏览器可以安全地存储键值对,比使用 cookie 更加直观. Web Storage 包含如下两种机制: sessionStorage 为每 ...
- 微信小程序把玩(三十六)Storage API
原文:微信小程序把玩(三十六)Storage API 其实这个存储在新建Demo的时候就已经用到了就是存储就是那个logs日志,数据存储主要分为同步和异步 异步存储方法: 存数据 wx.setStor ...
- Web Storage API:localStorage 和 SessionStorage
Web Storage API 提供了存储机制,通过该机制,浏览器可以安全地存储键值对,比使用 cookie 更加直观. 参考:https://developer.mozilla.org/zh-CN/ ...
- web API简介(三):客户端储存之Web Storage API
概述 前篇:web API简介(二):客户端储存之document.cookie API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. W ...
- Web Storage API的介绍和使用
目录 简介 浏览器的本地存储技术 Web Storage相关接口 浏览器兼容性 隐身模式 使用Web Storage API 总结 简介 Web Storage为浏览器提供了方便的key value存 ...
- HTML5 Storage API
原文:HTML5 Storage API Web Storage是HTML5引入的一个非常重要的功能,可以在客户端本地存储数据,类似HTML4的cookie,但可实现功能要比cookie强大的多. 在 ...
- 开放数据接口 API 简介与使用场景、调用方法
此文章对开放数据接口 API 进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用. 在给大家分享的一系列软件开发视频课程中,以及在我们的社区微信群聊天中,都积极地鼓励大家开 ...
- web API简介(四):客户端储存之IndexedDB API
概述 前篇:web API简介(三):客户端储存之Web Storage API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. Index ...
- web API简介(一):API,Ajax和Fetch
概述 今天逛MDN,无意中看到了web API简介,觉得挺有意思的,就认真读了一下. 下面是我在读的时候对感兴趣的东西的总结,供自己开发时参考,相信对其他人也有用. 什么是API API (Appli ...
随机推荐
- [程序员代码面试指南]字符串问题-字符串匹配问题(DP)
问题描述 字符串str,模式串exp. 必须保证str中无'.'和'星号'字符,并且exp中'星号'不出现在首位,且无连续两个'星号'.PS星号是字符只是暂时没找到markdown的星号转义字符. ' ...
- node.js conditionDebug VScode 配置
launch.json { // 使用 IntelliSense 了解相关属性. // 悬停以查看现有属性的描述. // 欲了解更多信息,请访问: https://go.microsoft.com/f ...
- python基础入门语法和变量类型(二)
列表 列表是 Python 中使用最频繁的数据类型,它可以完成大多数集合类的数据结构实现,可以包含不同类型的元素,包括数字.字符串,甚至列表(也就是所谓的嵌套). 和字符串一样,可以通过索引值或者切片 ...
- Python 之父为什么嫌弃 lambda 匿名函数?
Python 支持 lambda 匿名函数,其扩展的 BNF 表示法是lambda_expr ::= "lambda" [parameter_list] ":" ...
- SpringBoot框架:两个方法同时调用时父方法使内部方法的DataSource注解失效的解决办法
一.问题如下: 使用的是SpringBoot框架:通过AOP和自定义注解完成druid连接池的动态数据源切换(三)中的两个数据库spring_boot_demo和other_data. 在UserCo ...
- 吴恩达-机器学习+udacity从机器学习到深度学习
- pwnable.kr-cmd1-witeup
执行分析程序,知过滤掉了flag.sh.tmp字段,但在linux下可通过通配符匹配文件哦. 哦对,参数输入的命令中,没有环境变量的支持,所有文件和命令必须用绝对路径哦.
- 《我想进大厂》之MQ夺命连环11问
继之前的mysql夺命连环之后,我发现我这个标题被好多套用的,什么夺命zookeeper,夺命多线程一大堆,这一次,开始面试题系列MQ专题,消息队列作为日常常见的使用中间件,面试也是必问的点之一,一起 ...
- linux_基础调优
1. 配置授时服务,使用阿里云的授时服务 echo -e "# update time\n*/5 * * * * /usr/sbin/ntpdate time1.aliyun.com &am ...
- 【小白学PyTorch】16 TF2读取图片的方法
[新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.NLP等多个学术交流分群和水群唠嗑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx645016617. 参考 ...