zoukankan      html  css  js  c++  java
  • 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 存满的问题?

    1、划分域名。各域名下的存储空间由各业务组统一规划使用

    2、跨页面传数据:考虑单页应用、优先采用 url 传数据

    3、最后的兜底方案:清掉别人的存储

    互相伤害其实是个好办法

    在已然发展很久的业务中,我们怎么解决此问题呢?

    const QUOTA_EXCEEDED_ERR_CODE = 22
    function write (key, data) {
        try {
            localStorage.setItem(key, data);
        } catch (e) {
            if (e.code === QUOTA_EXCEEDED_ERR_CODE) {
                localStorage.clear();
                localStorage.setItem(key, data);
            }
        }
    }
    

    上面这个方法还是有点问题,因为它把自己业务要用的东西也给删了,所以自己的业务最好统一在 key 上加一个前缀,清空 localStorage 时只删别人的。

    有的同学可能会担心,这样会不会对其它业务造成伤害?或者产生一些难以发现的 bug。其实这种担心很大程度上是因为忽略了实际的使用场景。用户用同一个设备打开同一个 app,在同一个时间只能访问一个业务,因此不会存在某个业务正在使用过程中,localStorage 被其它业务清掉的场景,除非!除非有交叉的业务场景。

    一、如何得到localStorage已使用容量

    (function(){
        if(!window.localStorage) {
            console.log('浏览器不支持localStorage');
        }
        var size = 0;
        for(item in window.localStorage) {
            if(window.localStorage.hasOwnProperty(item)) {
                size += window.localStorage.getItem(item).length;
            }
        }
        console.log('当前localStorage已使用容量为' + (size / 1024).toFixed(2) + 'KB');
    })()

    二、如何获取localStorage最大容量

    通过上面的分析,其实思路基本是一样的,都是通过字符长度来判断。

    (function() {
       if(!window.localStorage) {
       console.log('当前浏览器不支持localStorage!')
       }    var test = '0123456789';
       var add = function(num) {
         num += num;
         if(num.length == 10240) {
           test = num;
           return;
         }
         add(num);
       }
       add(test);
       var sum = test;
       var show = setInterval(function(){
          sum += test;
          try {
           window.localStorage.removeItem('test');
           window.localStorage.setItem('test', sum);
           console.log(sum.length / 1024 + 'KB');
          } catch(e) {
           console.log(sum.length / 1024 + 'KB超出最大限制');
           clearInterval(show);
          }
       }, 0.5)
     })()

    注:上面代码可能卡死浏览器

    相关链接:

    https://www.cnblogs.com/kidney/p/9058352.html

    https://www.cnblogs.com/MonkeyKingK/p/5499831.html

  • 相关阅读:
    HDU 1816, POJ 2723 Get Luffy Out(2-sat)
    [Transducer] Make an Into Helper to Remove Boilerplate and Simplify our Transduce API
    [ML] Daily Portfolio Statistics
    [Javascript] Transduce over any Iteratable Collection
    [Javascript] Improve Composition with the Compose Combinator
    [Mobx] Using mobx to isolate a React component state
    [Javascript] Simplify Creating Immutable Data Trees With Immer
    [React Native] Dismiss the Keyboard in React Native
    [CSSinJS] Convert Sass (SCSS) Styled Button to CSSinJS with JavaScript Templates and Variables
    [React Native] Use the SafeAreaView Component in React Native for iPhone X Compatibility
  • 原文地址:https://www.cnblogs.com/7qin/p/localStorage_m.html
Copyright © 2011-2022 走看看