localstorage

2024-04-30 16:14

1. localstorage

 时间:默认无时间限制;   大小:5M,不同浏览器不确定,大致是这个数;   如果存储内容超过5M怎么办;
   最近面试的时候关于html5API总会被问到 localStorage 的问题, 对于一般的问题很简单,无非就是
   上面的三个问题大部分同学都可以回答出来,那么,面试官的问题来了:
    字符串最大容量是5M,那么我如果存储容量溢出了怎么办? 
                                            最后一次溢出的字符串是会存储到最大容量停止还是不会存储? 
                                            既然存在安全问题,那么localStorage的使用就不是绝对安全的,如何更安全的使用localStorage? 

localstorage

2. localStorage是什么?

局部存储器。它是html5新增的一个本地存储API,所谓localStorage就是一个小仓库的意思,它有5M的大小空间,存储在浏览器中,我们可以通过js来操纵localStorage。
localStorage的用法
1、localStorage通过使用setItem(key,value)来设置元素以及值,如localStorage.setItem("name","chenyejun")
2、使用getItem(key)来获取元素值,如localStorage.getItem("name");
3、使用removeItem(key)清除key值,如localStorage.removeItem("name");
4、使用localStorage.clear()清除所有的key值;
5、使用localStorage.length可以获取本地存储key的个数;
6、按照序号读取本地存储变量的key值,使用localStorage.key(i)。

3. localStorage是什么

局部存储器。它是html5新增的一个本地存储API,所谓localStorage就是一个小仓库的意思,它有5M的大小空间,存储在浏览器中,我们可以通过js来操纵localStorage。
localStorage的用法
1、localStorage通过使用setItem(key,value)来设置元素以及值,如localStorage.setItem("name","chenyejun")
2、使用getItem(key)来获取元素值,如localStorage.getItem("name");
3、使用removeItem(key)清除key值,如localStorage.removeItem("name");
4、使用localStorage.clear()清除所有的key值;
5、使用localStorage.length可以获取本地存储key的个数;
6、按照序号读取本地存储变量的key值,使用localStorage.key(i)。

localStorage是什么

4. localStorage 存满了怎么办?

1、a.meituan.com 和 b.meituan.com 这两个域能够共享同一个 localStorage 吗?
  
 2、在 webview 中打开一个页面:i.meituan.com/home.html,点击一个按钮,调用 js 桥打开一个新的 webview:i.meituan.com/list.html,这两个分属不同 webview 的页面能共享同一个 localStorage 吗?
  
 3、如果 localStorage 存满了,再往里存东西,或者要存的东西超过了剩余容量,会发生什么?
  
 1、同一个域名(document.domain)共享同一个 localStorage,a.meituan.com 和 b.meituan.com 是两个域名,所以不能共享
  
 2、能。相当于同一个浏览器的不同标签页。不同浏览器之间不能共享。
  
 3、存不进去并报错(QuotaExceededError)
  
 在大公司,同一个域名下可能存在几十上百条业务线,每条业务线都可能因为各种理由往 localStorage 里塞东西,跨页面传数据啦、缓存啦、离线化啦、性能优化啦...,5M 看起来很多,其实很快就用完了。而开发时基本无感知,是因为大家都只访问自己的业务,但用户会访问各种业务,时间一久,很容易就存满了,凡是严重依赖 localStorage 的业务流程都存在风险,写可能出问题,读自然也会出问题。
  
 一种容易想到的方案是,当 localStorage 存满后降级到 sessionStorage 里。看上去没啥问题,但实际业务中 app 内 h5 页面跳转常常采用新打开 webview 的方式,这么做的好处是关闭一个 webview 可以直接回到上一个页面,而不用重新加载页面,对于订单填写这类带有状态的页面就很需要这么做。新打开 webview 等于新打开一个会话,而 sessionStorage 只能存在于同一个会话中,因此 sessionStorage 无法跨页面共享。
  
 那降级到 cookie 里呢?cookie 一共才 50 个,总大小不超过 4k,作为 backup 过于脆弱,而且还会影响请求的效率。如果后端对请求头大小做了限制,还可能产生 413 错误,导致请求被拦截。
  
 那降级到 url 上呢?很麻烦。比如有一个交互流程是这样的:页面 A => 页面 B => 页面 C,如果页面 A 的数据要传到页面 C,就得通过页面 B 做一层中转。而且 url 长度也是有限制的。
  
 单页应用解决跨页面传数据就很简单,改造成单页应用呢?这个就得估算成本,看老板们认不认可了,而且原有应用积累了大量的业务逻辑,没有注释,没有测试用例,需求文档散落在不知名的角落,你真能保证重新做的和原来的功能一模一样吗。
  
 我们还可以求助客户端同学,通过 js bridge 提供一个仿 localStorage 的东西,不过要考虑版本的问题,新版 app 里使用了客户端提供的 store,怎么兼顾老版 app,而且还要考虑兼容浏览器、微信。所以这种方案也只能解决一部分问题,当然,如果 h5 的流量绝大多数都在 app 里,那么这种方案是可以解决一大部分问题的,不过客户端提供的存储可不见得比原生的存储可靠,还是得加 backup。
  
 我们还可以求助后端同学,多加几个字段甚至多加几个接口,不过这涉及到核心业务流程的改造,风险不小,而且不见得能完全解决问题,也无法永久的解决问题。
  
 我们还可以来一招互相伤害大法,那就是把别人存的东西都删掉。。。
  
 localStorage 是个好东西,不用,这是因噎废食,用,又很难统一和约束各业务线的用法,一旦放开用,就总会面临存满的风险。跟你在同一个域名下做开发的人可能跟你不在同一栋楼,甚至可能不在同一个城市,你有那个影响力去统一所有人的使用规范吗。
  
 还有一个很讨厌的事情:safari 在隐私模式下不支持 localStorage 的存取(ios11 以下),这种情况比较罕见,但如果出了客诉,也是个大坑。
  
 localStorage 归根结底就两个作用:持久化存储与跨页面传数据。持久化存储不会出问题,存不进去就存不进去呗,取不出来就去其它地方取,或者不取。问题就出在跨页面传数据上,上一个页面因为 localStorage 存满导致数据没有写入,下一个页面读取数据为空,从而导致错误。
  
 同一个域名共享同一个 localStorage,而同一个域名下存在过多独立的业务线,业务线之间各自为政,毫无节制的攫取公共资源,这就是 localStorage 溢出问题的根源。
  
 就我观察的情况来看,很多公司都喜欢把 h5 页面挂在 i.xxx.com 或 m.xxx.com 下,然后通过路径划分业务,比如 i.xxx.com/project-a, i.xxx.com/project-b...,随着业务发展,越来越多的业务都加到 i.xxx.com 中,“公地悲剧”就无可奈何的产生了,而且积重难返。我以前在的团队也是如此,用 h5、js、css 这样的类型名称来划分目录,初期东西少,自然没问题,但后来所有应用都把资源塞到 js 文件夹、css 文件夹下,一个文件夹包含了来自五湖四海的上百个文件,维护起来十分难受。
  
 通过应用类型划分,而不是通过业务类型划分,这是最初架构策略的问题。如果 a 业务挂在 a.xxx.com 下,b 业务挂在 b.xxx.com 下,每个业务有独立的团队维护,localStorage 从公共资源变成团队的私有财产,或许这样才能从根源上解决 localStorage 无限膨胀的问题。有网友提出对 i.xxx.com 进一步划分子域,其实也是这个思路。
  
 假设我们回到起点,从零建设前端工程,我们怎么避免 localStorage 存满的问题?
  
 1、划分域名。各域名下的存储空间由各业务组统一规划使用
  
 2、跨页面传数据:考虑单页应用、优先采用 url 传数据
  
 3、最后的兜底方案:清掉别人的存储
  
 在已然发展很久的业务中,我们怎么解决此问题呢?
  
 上面这个方法还是有点问题,因为它把自己业务要用的东西也给删了,所以自己的业务最好统一在 key 上加一个前缀,清空 localStorage 时只删别人的。
  
 有的同学可能会担心,这样会不会对其它业务造成伤害?或者产生一些难以发现的 bug。其实这种担心很大程度上是因为忽略了实际的使用场景。用户用同一个设备打开同一个 app,在同一个时间只能访问一个业务,因此不会存在某个业务正在使用过程中,localStorage 被其它业务清掉的场景,除非!除非有交叉的业务场景。
  
 没有银弹,没有十全十美的方案。
  
 掘金网友@FE 提出用 indexedDB 存文件类型的数据,localStorage 存业务数据,这是一种可以缓解问题的方案
  
 本文转自: https://www.cnblogs.com/kidney/p/9058352.html

5. 浅谈localStorage的性能

  中文存储不简单 
      localStorage, perhaps not so harmful 
      PSA: DOM localStorage considered harmful 
    CateDta存储的是一个类目数组  文件大小在1M左右, 数组长度为40 
   在谷歌上面 测试了十组结果  得出结果:
   在谷歌上面 测试了十组结果 计算平均值:
   以500 为标准的时候 在谷歌上面 测试了十组结果  得出
   得出读取速度  分批次的时候 平均读取速度是7.9ms  整体存入的平均速度 16.6ms
   在谷歌上面 测试了十组结果:   分别存入  存入5次 平均值是47.6ms  整体存入 存入5次的话 37.5ms
    https://www.cnblogs.com/shinnyChen/p/3779782.html 
    https://www.jianshu.com/p/a47baf68addb 
    localStorage读取性能 
    HTML5新特性之localStorage的使用技巧,不看看你可能真的不知道 

浅谈localStorage的性能

6. localstorage的使用(缓存)

在微信公众号看到了一篇文章,截取一些重点做笔记,篇尾附上原文出处。
  
  1. localStorage出现的需求和目的 
  
     localStorage出现是为了弥补cookie(4k)容量过小的问题,localStorage在大部分电脑是5m。与localStorage同时出现的还有sessionStorage,sessionStorage是会话级,页面关闭,自动清除,localStorage需要清除行为才能清除。
  
  2. 操作方法 
  
     新增(替换),获取,单个移除,全部移除:
  
     1. window.localStorage.setItem(key,value)
  
     2. window.localStorage.getItem(key)
  
     3. window.localStorage.removeItem(key)
  
     4. window.localStorage.clear(key)
  
     window是可以省略的,且需要注意的是:简单数据类型和复杂数据类型都可以存储在localStorage当中,但是对于引用数据类型,需要进行序列化和反序列化,说人话就是用JSON.stringify()转换为json字符串,同理获取的时候可以恢复为原来的数据
  
  3. 注意的地方 
  
     1. 当存量接近最大值时,getItem的速度大大降低。
  
     2. setItem时,如果存量加上添加量大于上限,那么就会出错,需要捕捉错误:
  
         try {  
  
               localStorage.setItem(key, value);
  
         } catch(e) {
  
               if (isQuotaExceeded(e)) {
  
                     // Storage full, maybe notify user or do some clean-up
  
               }
  
         }
  
 function isQuotaExceeded(e) {  
  
   var quotaExceeded = false;
  
   if (e) {
  
     if (e.code) {
  
       switch (e.code) {
  
         case 22:
  
           quotaExceeded = true;
  
           break;
  
         case 1014:
  
           // Firefox
  
           if (e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
  
             quotaExceeded = true;
  
           }
  
           break;
  
       }
  
     } else if (e.number === -2147024882) {
  
       // Internet Explorer 8
  
       quotaExceeded = true;
  
     }
  
   }
  
   return quotaExceeded;
  
 }
  
  4. 加载和缓存静态资源 
  
     后边实在是太长,直接扔 原文 吧
最新文章
热门文章
推荐阅读