Storage API简介和存储限制与逐出策略

简介: 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)。


image.png


不同的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,我们看下他们的浏览器兼容性:


image.png


基本上,现代浏览器都支持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。还在不断的完善之中。感兴趣的朋友可以多多关注它的进展。


相关文章
|
2月前
|
XML 监控 API
跨平台销售策略:通过API同步不同市场的商品数据
在数字化时代,零售商和品牌经常需要在不同的在线市场上展示和销售商品。为了保持竞争力并确保一致的客户体验,商家必须确保其商品信息在所有渠道上保持同步和准确。这种需求催生了跨平台销售策略,其中一个关键组成部分就是利用应用程序编程接口(API)来同步不同市场的商品数据。
|
6月前
|
API 对象存储
可能是由于API请求的策略已经过期
可能是由于API请求的策略已经过期
55 3
|
3月前
|
数据挖掘 API
京东商品详情API:数据分析和挖掘以优化销售策略
商品关联分析:通过分析商品之间的关联规则,商家可以发现哪些商品经常一起被购买,从而制定捆绑销售或搭配销售策略,提高客单价和用户满意度。
|
1月前
|
分布式计算 API 数据处理
Flink【基础知识 01】(简介+核心架构+分层API+集群架构+应用场景+特点优势)(一篇即可大概了解flink)
【2月更文挑战第15天】Flink【基础知识 01】(简介+核心架构+分层API+集群架构+应用场景+特点优势)(一篇即可大概了解flink)
60 1
|
3月前
|
JavaScript 前端开发 IDE
Vue3【为什么选择Vue框架、Vue简介 、Vue API 风格 、Vue开发前的准备 、Vue项目目录结构 、模板语法、属性绑定 、 】(一)-全面详解(学习总结---从入门到深化)
Vue3【为什么选择Vue框架、Vue简介 、Vue API 风格 、Vue开发前的准备 、Vue项目目录结构 、模板语法、属性绑定 、 】(一)-全面详解(学习总结---从入门到深化)
50 1
|
8月前
|
API 开发者
币安合约现货策略交易接口API对接开发源代码详情
# 生成签名的函数(示例) def generate_signature(params, secret): signature = '' for key in sorted(params.keys()):
|
3月前
|
存储 Java API
你了解SpringBoot启动时API相关信息是用什么数据结构存储的吗?(上篇)
你了解SpringBoot启动时API相关信息是用什么数据结构存储的吗?(上篇)
32 0
|
3月前
|
算法 数据挖掘 程序员
数据挖掘之旅:京东商品详情API与销售策略的优化
曾经,数据是一座未知的金矿,静静地躺在无数的数据库和服务器中。而今,有了京东商品详情API,我们这些程序员终于找到了开采这座金矿的方法。
|
3月前
|
消息中间件 存储 Java
RocketMQ-初体验RocketMQ(06)-使用API操作RocketMQ ,理解RocketMQ的存储结构
RocketMQ-初体验RocketMQ(06)-使用API操作RocketMQ ,理解RocketMQ的存储结构
175 0
|
4月前
|
存储 NoSQL 分布式数据库
分布式NoSQL列存储数据库Hbase Java API(四)
分布式NoSQL列存储数据库Hbase Java API(四)
21 0