localStorage兼容问题小记

2019-02-11 | 4,437浏览 | 0评论 | 标签:localStorage sessionStorage cookie

localstorage.jpg

现代移动端浏览器几乎都支持localStorage/sessionStorage,注意是几乎!当部分浏览器开启无痕模式后,localStorage无效,但window对象下依然存在localStorage,甚至还有setItemgetItem方法,需要更严格的兼容判断。

以下是Quark(夸克)浏览器在正式和无痕两种模式下的localStorage.setItem方法的表现(sessionStorage同理):

正常模式function setItem(){[native code]}
无痕模式function (a,b){}

所以,无痕模式下setItem当然无效,而且不会抛出错误,神不知鬼不觉。getItem会得到null

在网上查了资料,比较偏向于localStorage和cookie合作的方式。

<script>
  // (以下操作cookie和storage方法在公司帅哥@jackie基础上修改)

  let storage = {
    // set localStorage/sessionStorage
    setStorage(name, value, type) {
      if (this.isSupportStorage()) {
        const storageName = (type || 'local') + 'Storage';
        if (typeof value !== 'object') {
          window[storageName].setItem(name, value);
        } else {
          value = JSON.stringify(value);
          window[storageName].setItem(name, value);
        }
      } else {
        this.setCookie(name, JSON.stringify(value), 7)
      }
    },

    // get localStorage/sessionStorage
    getStorage(name, type) {
      if (this.isSupportStorage()) {
        const storageName = (type || 'local') + 'Storage';
        return window[storageName].getItem(name) || '';
      } else {
        return this.getCookie(name) || ''
      }
    },

    // set cookie
    setCookie(key, val, day) {
      let exp = null;
      let expires = "";
      if (day) {
        exp = new Date();
        exp = new Date(exp.setTime(exp.getTime() + day * 24 * 60 * 60 * 1000)).toUTCString();
        expires = ";expires=" + exp;
      }
      document.cookie = key + "=" + escape(val) + expires;
    },

    // get cookie
    getCookie: function (name) {
      let cookie = document.cookie
      cookie = cookie.split(';').map(function (value) {
        return value.trim()
      }).reduce(function (obj, item) {
        let index = item.indexOf('=');
        obj[item.slice(0, index)] = item.slice(index + 1);
        return obj
      }, {});
      if (name) return (unescape(cookie[name]) || '');
      return unescape(cookie || '')
    },

    // 是否兼容
    isSupportStorage() {
      let ua = window.navigator.userAgent,
        notSupportBrowers = [];

      // 手动排除不支持的浏览器
      for (var i = 0; i < notSupportBrowers.length; i++) {
        if (ua.indexOf(notSupportBrowers[i]) > -1) {
          return 0
        }
      }

      // 自动检测
      try {
        window.localStorage.setItem('isSupportStorage', 'test');
        window.localStorage.removeItem('isSupportStorage');
        //部分浏览器开启无痕模式后,setItem、getItem方法失效
        return this.isNative(window.localStorage.setItem);
      } catch (e) {
        return 0;
      }
    },

    // 是否原生支持
    isNative(fn) {
      return (/\{\s*\[native code\]\s*\}/).test('' + fn);
    }
  }

  storage.setStorage('test', 'hello');
  document.write('你的浏览器'+(storage.isSupportStorage()?'':'不')+'支持localStorage'+'<br />');
  document.write('数据将存于'+(storage.isSupportStorage()?'localStorage':'cookie')+'<br />');
  document.write('test的值为'+storage.getStorage('test')+'<br />');

</script>

注:以上代码仅作为探讨,不保证没有其它问题,请自行实践测试。

(本篇完。有疑问欢迎留言探讨)

留言:

*

* (方便回复通知)

打赏
编辑代码 运行结果
退出