温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

HTML5中Localstorage怎么使用

发布时间:2022-03-07 17:13:58 来源:亿速云 阅读:150 作者:iii 栏目:web开发

这篇文章主要讲解了“HTML5中Localstorage怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“HTML5中Localstorage怎么使用”吧!

什么是localstorage

  前几天在老项目中发现有对cookie的操作觉得很奇怪,咨询下来是要缓存一些信息,以避免在URL上面传递参数,但没有考虑过cookie会带来什么问题:

  ① cookie大小限制在4k左右,不适合存业务数据

  ② cookie每次随HTTP事务一起发送,浪费带宽

  我们是做移动项目的,所以这里真实适合使用的技术是localstorage,localstorage可以说是对cookie的优化,使用它可以方便在客户端存储数据,并且不会随着HTTP传输,但也不是没有问题:

  ① localstorage大小限制在500万字符左右,各个浏览器不一致

  ② localstorage在隐私模式下不可读取

  ③ localstorage本质是在读写文件,数据多的话会比较卡(firefox会一次性将数据导入内存,想想就觉得吓人啊)

  ④ localstorage不能被爬虫爬取,不要用它完全取代URL传参

  瑕不掩瑜,以上问题皆可避免,所以我们的关注点应该放在如何使用localstorage上,并且是如何正确使用。

localstorage的使用

  基础知识

  localstorage存储对象分为两种:

  ① sessionStrage: session即会话的意思,在这里的session是指用户浏览某个网站时,从进入网站到关闭网站这个时间段,session对象的有效期就只有这么长。

  ② localStorage: 将数据保存在客户端硬件设备上,不管它是什么,意思就是下次打开计算机时候数据还在。

  两者区别就是一个作为临时保存,一个长期保存。

  这里来一段简单的代码说明其基本使用:

XML/HTML Code复制内容到剪贴板

<div id="msg" style="margin: 10px 0; border: 1px solid black; padding: 10px; width: 300px;   

  height: 100px;">  

</div>  

<input type="text" id="text" />  

<select id="type">  

  <option value="session">sessionStorage</option>  

  <option value="local">localStorage</option>  

</select>  

<button onclick="save();">  

  保存数据</button>  

<button onclick="load();">  

  读取数据</button>  

<script type="text/javascript">  

  var msg = document.getElementById('msg'),   

            text = document.getElementById('text'),   

            type = document.getElementById('type');   

  function save() {   

    var str = text.value;   

    var t = type.value;   

    if (t == 'session') {   

      sessionStorage.setItem('msg', str);   

    } else {   

      localStorage.setItem('msg', str);   

    }   

  }   

  function load() {   

    var t = type.value;   

    if (t == 'session') {   

      msg.innerHTML = sessionStorage.getItem('msg');   

    } else {   

      msg.innerHTML = localStorage.getItem('msg');   

    }   

  }   

</script>  

 真实场景

  实际工作中对localstorage的使用一般有以下需求:

  ① 缓存一般信息,如搜索页的出发城市,达到城市,非实时定位信息

  ② 缓存城市列表数据,这个数据往往比较大

  ③ 每条缓存信息需要可追踪,比如服务器通知城市数据更新,这个时候在最近一次访问的时候要自动设置过期

  ④ 每条信息具有过期日期状态,在过期外时间需要由服务器拉取数据

XML/HTML Code复制内容到剪贴板

define([], function () {   

  var Storage = _.inherit({   

    //默认属性   

    propertys: function () {   

      //代理对象,默认为localstorage   

      this.sProxy = window.localStorage;   

      //60 * 60 * 24 * 30 * 1000 ms ==30天   

      this.defaultLifeTime = 2592000000;   

      //本地缓存用以存放所有localstorage键值与过期日期的映射   

      this.keyCache = 'SYSTEM_KEY_TIMEOUT_MAP';   

      //当缓存容量已满,每次删除的缓存数   

      this.removeNum = 5;   

    },   

    assert: function () {   

      if (this.sProxy === null) {   

        throw 'not override sProxy property';   

      }   

    },   

    initialize: function (opts) {   

      this.propertys();   

      this.assert();   

    },   

    /*   

    新增localstorage   

    数据格式包括唯一键值,json字符串,过期日期,存入日期   

    sign 为格式化后的请求参数,用于同一请求不同参数时候返回新数据,比如列表为北京的城市,后切换为上海,会判断tag不同而更新缓存数据,tag相当于签名   

    每一键值只会缓存一条信息   

    */   

    set: function (key, value, timeout, sign) {   

      var _d = new Date();   

      //存入日期   

      var indate = _d.getTime();   

      //最终保存的数据   

      var entity = null;   

      if (!timeout) {   

        _d.setTime(_d.getTime() + this.defaultLifeTime);   

        timeout = _d.getTime();   

      }   

      //   

      this.setKeyCache(key, timeout);   

      entity = this.buildStorageObj(value, indate, timeout, sign);   

      try {   

        this.sProxy.setItem(key, JSON.stringify(entity));   

        return true;   

      } catch (e) {   

        //localstorage写满时,全清掉   

        if (e.name == 'QuotaExceededError') {   

          //            this.sProxy.clear();   

          //localstorage写满时,选择离过期时间最近的数据删除,这样也会有些影响,但是感觉比全清除好些,如果缓存过多,此过程比较耗时,100ms以内   

          if (!this.removeLastCache()) throw '本次数据存储量过大';   

          this.set(key, value, timeout, sign);   

        }   

        console && console.log(e);   

      }   

      return false;   

    },   

    //删除过期缓存   

    removeOverdueCache: function () {   

      var tmpObj = null, i, len;   

      var now = new Date().getTime();   

      //取出键值对   

      var cacheStr = this.sProxy.getItem(this.keyCache);   

      var cacheMap = [];   

      var newMap = [];   

      if (!cacheStr) {   

        return;   

      }   

      cacheMap = JSON.parse(cacheStr);   

      for (i = 0, len = cacheMap.length; i < len; i++) {   

        tmpObj = cacheMap[i];   

        if (tmpObj.timeout < now) {   

          this.sProxy.removeItem(tmpObj.key);   

        } else {   

          newMap.push(tmpObj);   

        }   

      }   

      this.sProxy.setItem(this.keyCache, JSON.stringify(newMap));   

    },   

    removeLastCache: function () {   

      var i, len;   

      var num = this.removeNum || 5;   

      //取出键值对   

      var cacheStr = this.sProxy.getItem(this.keyCache);   

      var cacheMap = [];   

      var delMap = [];   

      //说明本次存储过大   

      if (!cacheStr) return false;   

      cacheMap.sort(function (a, b) {   

        return a.timeout - b.timeout;   

      });   

      //删除了哪些数据   

      delMap = cacheMap.splice(0, num);   

      for (i = 0, len = delMap.length; i < len; i++) {   

        this.sProxy.removeItem(delMap[i].key);   

      }   

      this.sProxy.setItem(this.keyCache, JSON.stringify(cacheMap));   

      return true;   

    },   

    setKeyCache: function (key, timeout) {   

      if (!key || !timeout || timeout < new Date().getTime()) return;   

      var i, len, tmpObj;   

      //获取当前已经缓存的键值字符串   

      var oldstr = this.sProxy.getItem(this.keyCache);   

      var oldMap = [];   

      //当前key是否已经存在   

      var flag = false;   

      var obj = {};   

      obj.key = key;   

      obj.timeout = timeout;   

      if (oldstr) {   

        oldMap = JSON.parse(oldstr);   

        if (!_.isArray(oldMap)) oldMap = [];   

      }   

      for (i = 0, len = oldMap.length; i < len; i++) {   

        tmpObj = oldMap[i];   

        if (tmpObj.key == key) {   

          oldMap[i] = obj;   

          flag = true;   

          break;   

        }   

      }   

      if (!flag) oldMap.push(obj);   

      //最后将新数组放到缓存中   

      this.sProxy.setItem(this.keyCache, JSON.stringify(oldMap));   

    },   

    buildStorageObj: function (value, indate, timeout, sign) {   

      var obj = {   

        value: value,   

        timeout: timeout,   

        sign: sign,   

        indate: indate   

      };   

      return obj;   

    },   

    get: function (key, sign) {   

      var result, now = new Date().getTime();   

      try {   

        result = this.sProxy.getItem(key);   

        if (!result) return null;   

        result = JSON.parse(result);   

        //数据过期   

        if (result.timeout < now) return null;   

        //需要验证签名   

        if (sign) {   

          if (sign === result.sign)   

            return result.value;   

          return null;   

        } else {   

          return result.value;   

        }   

      } catch (e) {   

        console && console.log(e);   

      }   

      return null;   

    },   

    //获取签名   

    getSign: function (key) {   

      var result, sign = null;   

      try {   

        result = this.sProxy.getItem(key);   

        if (result) {   

          result = JSON.parse(result);   

          sign = result && result.sign   

        }   

      } catch (e) {   

        console && console.log(e);   

      }   

      return sign;   

    },   

    remove: function (key) {   

      return this.sProxy.removeItem(key);   

    },   

    clear: function () {   

      this.sProxy.clear();   

    }   

  });   

  Storage.getInstance = function () {   

    if (this.instance) {   

      return this.instance;   

    } else {   

      return this.instance = new this();   

    }   

  };   

  return Storage;   

});  

这段代码包含了localstorage的基本操作,并且对以上问题做了处理,而真实的使用还要再抽象:

XML/HTML Code复制内容到剪贴板

define(['AbstractStorage'], function (AbstractStorage) {   

  var Store = _.inherit({   

    //默认属性   

    propertys: function () {   

      //每个对象一定要具有存储键,并且不能重复   

      this.key = null;   

      //默认一条数据的生命周期,S为秒,M为分,D为天   

      this.lifeTime = '30M';   

      //默认返回数据   

      //      this.defaultData = null;   

      //代理对象,localstorage对象   

      this.sProxy = new AbstractStorage();   

    },   

    setOption: function (options) {   

      _.extend(this, options);   

    },   

    assert: function () {   

      if (this.key === null) {   

        throw 'not override key property';   

      }   

      if (this.sProxy === null) {   

        throw 'not override sProxy property';   

      }   

    },   

    initialize: function (opts) {   

      this.propertys();   

      this.setOption(opts);   

      this.assert();   

    },   

    _getLifeTime: function () {   

      var timeout = 0;   

      var str = this.lifeTime;   

      var unit = str.charAt(str.length - 1);   

      var num = str.substring(0, str.length - 1);   

      var Map = {   

        D: 86400,   

        H: 3600,   

        M: 60,   

        S: 1   

      };   

      if (typeof unit == 'string') {   

        unitunit = unit.toUpperCase();   

      }   

      timeout = num;   

      if (unit) timeout = Map[unit];   

      //单位为毫秒   

      return num * timeout * 1000 ;   

    },   

    //缓存数据   

    set: function (value, sign) {   

      //获取过期时间   

      var timeout = new Date();   

      timeout.setTime(timeout.getTime() + this._getLifeTime());   

      this.sProxy.set(this.key, value, timeout.getTime(), sign);   

    },   

    //设置单个属性   

    setAttr: function (name, value, sign) {   

      var key, obj;   

      if (_.isObject(name)) {   

        for (key in name) {   

          if (name.hasOwnProperty(key)) this.setAttr(k, name[k], value);   

        }   

        return;   

      }   

      if (!sign) sign = this.getSign();   

      //获取当前对象   

      obj = this.get(sign) || {};   

      if (!obj) return;   

      obj[name] = value;   

      this.set(obj, sign);   

    },   

    getSign: function () {   

      return this.sProxy.getSign(this.key);   

    },   

    remove: function () {   

      this.sProxy.remove(this.key);   

    },   

    removeAttr: function (attrName) {   

      var obj = this.get() || {};   

      if (obj[attrName]) {   

        delete obj[attrName];   

      }   

      this.set(obj);   

    },   

    get: function (sign) {   

      var result = [], isEmpty = true, a;   

      var obj = this.sProxy.get(this.key, sign);   

      var type = typeof obj;   

      var o = { 'string': true, 'number': true, 'boolean': true };   

      if (o[type]) return obj;   

      if (_.isArray(obj)) {   

        for (var i = 0, len = obj.length; i < len; i++) {   

          result[i] = obj[i];   

        }   

      } else if (_.isObject(obj)) {   

        result = obj;   

      }   

      for (a in result) {   

        isEmpty = false;   

        break;   

      }   

      return !isEmpty ? result : null;   

    },   

    getAttr: function (attrName, tag) {   

      var obj = this.get(tag);   

      var attrVal = null;   

      if (obj) {   

        attrVal = obj[attrName];   

      }   

      return attrVal;   

    }   

  });   

  Store.getInstance = function () {   

    if (this.instance) {   

      return this.instance;   

    } else {   

      return this.instance = new this();   

    }   

  };   

  return Store;   

});  

  我们真实使用的时候是使用store这个类操作localstorage,代码结束简单测试:

201579150514318.jpg (488&times;184)

 存储完成,以后都不会走请求,于是今天的代码基本结束 ,最后在android Hybrid中有一后退按钮,此按钮一旦按下会回到上一个页面,这个时候里面的localstorage可能会读取失效!一个简单不靠谱的解决方案是在webapp中加入:

XML/HTML Code复制内容到剪贴板

window.onunload = function () { };//适合单页应用

感谢各位的阅读,以上就是“HTML5中Localstorage怎么使用”的内容了,经过本文的学习后,相信大家对HTML5中Localstorage怎么使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI