Safari無痕模式下,storage被禁用問題

前言

Safari開啓無痕模式後,localStorage和sessionStorage爲空,對其進行set操做也會報錯,也就是說這種狀況下,storage是被禁止使用了。接下來講一下解決方法。瀏覽器

解決方案服務器

咱們項目框架上的解決方法是對storage進行一層封裝,遇到這種開啓無痕模式的狀況,會定義一個window的全局變量,把以前準備存放到storage的內容改成存到這個全局變量中。cookie

注意,無痕模式下localStorage和sessionStorage對象自己依然是存在的,只是調用setItem方法是會報錯。下面是無痕模式下報錯的截圖:session

因此正確的判斷代碼應該是這樣:框架

try {
      sessionStorage.setItem('private_test', 1);
    } catch (e) {
      //無痕模式
    }
複製代碼

咱們會另外定義一個NameStorage對象,在原生storage失效時使用:this

// 隱私模式下面,把臨時值存到window.name中去
  function NameStorage(type) {
    this.store = NameStorage[type];
  }


  Object.assign(NameStorage.prototype, {
    getItem: function(key) {
      return this.store[key];
    },
    setItem: function(key, value) {
      this.store[key] = value;
      this._saveNameValue();
    },
    removeItem: function(key) {
      delete this.store[key];
      this._saveNameValue();
    },
    clear: function() {
      this.store = {};
      this._saveNameValue();
    },
    _saveNameValue: function() {
      var ret = {
        session: NameStorage.session,
        local: NameStorage.local
      }

      window.name = JSON.stringify(ret);
    }
  });
複製代碼

上面會把全部的local和session數據存儲到window.name上去,而後在每一個頁面啓動時,調用一下keepName方法,把window.name的數據拿下來放到NameStorage上面。這時候,只須要調用new NameStorage('local')來代替localStorage進行操做就好了spa

function keepName () {
    if (keepName.done) {
      return;
    }

    var ret;

    if (window.name) {
      try {
        ret = JSON.parse(window.name);
      } catch (e) {
        ret = {};
      }
    }

    if (!_.isPlainObject(ret)) {
      ret = {};
    }


    if (!ret.session) {
      ret.session = {};
    }

    if (!ret.local) {
      ret.local = {};
    }


    NameStorage.session = ret.session;
    NameStorage.local = ret.local;
    keepName.done = true;
  }
複製代碼

另一些補充

● 無痕模式下,localStorage和sessionStorage的報錯信息是:QuotaExceededError,code爲22,這個實際上是storage存儲空間用完了報的錯,就好比當前瀏覽器storage內存爲5mb,你已經存儲了5mb的數據後,再進行setItem操做就會報這個錯誤。prototype

● 因此我猜測無痕模式下,瀏覽器是把storage的內存先清空,而後再設置最大值爲0,這樣調用setItem就直接報錯了。code

● 另外無痕模式下cookie是可使用的,大概由於cookie是跟服務器有關,而storage是屬於瀏覽器的特性吧。對象

● 最後還有一種狀況,就是無痕模式下打開了某個頁面,而後把瀏覽器關閉再打開,這個時候會打開訪問的頁面,可是window.name已經丟失了,因此就拿不到之前存儲的數據了。這種狀況只能頁面作容錯處理了。

相關文章
相關標籤/搜索