欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

QuotaExceededError The quota has been exceeded

程序员文章站 2022-03-29 19:05:58
...

(一)前言
我首先描述下,这种报错出现的场景

  1. ios <= 10 真机 Safari 的无痕浏览模式
  2. 使用localStorage or sessionStorage 的 setItem

当然,问题肯定社区有解决方案,以下链接可以满足你想要的答案
问题链接1
问题链接2
问题链接3

(二)解决过程

如果你看完,那么问题可以总结为,两个方向

  1. 是我们h5站点增加检测是否支持,并提示用户切换模式
  2. 我们在不支持情况,默认切到cookie

当然因为cookie本身储存空间不大,所以建议如果本地存储大量数据,不建议用2,以下为2中支持提供代码

检测是否支持

function isStorageNameSupported(storage) {
    var testKey = 'test';
    try {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return storage in win && win[storage];
    } catch (error) {
        return false;
    }
}

默认切换到cookie

因为cookie需要字符串处理,所以安装一个包
js-cookie

首先实现一个storageHelper类,提供切换

import Cookies from 'js-cookie';
import { isObject } from 'lodash';

class StorageHelper {
  private supportKey = 'supportStorage'; // 测试是否支持Storage的key
  private supportStorage = true; // 支持Storage
  private storage; // 存储实例化的storage
  public constructor(storage) {
    try {
      this.storage = storage;
      this.storage.setItem(this.supportKey, '1');
    } catch (e) {
      // ios 10 无痕QuotaExceededError
      if (e.code === 22) {
        this.supportStorage = false;
        return;
      }
    } finally {
      this.storage.removeItem(this.supportKey);
    }
  }

  public transformSet(data) {
    if (isObject(data)) {
      return JSON.stringify(data);
    }
    return data;
  }
  public setItem(key, value = {}) {
    if (this.supportStorage) {
      return this.storage.setItem(key, this.transformSet(value));
    }
    return Cookies.set(key, this.transformSet(value));
  }

  public transformGet(data) {
    if (data && data.startsWith('{')) {
      return JSON.parse(data);
    }
    return data;
  }
  public getItem(key) {
    if (this.supportStorage) {
      return this.transformGet(this.storage.getItem(key));
    }
    return this.transformGet(Cookies.get(key));
  }

  public removeItem(key) {
    if (this.supportStorage) {
      return this.storage.removeItem(key);
    }
    return Cookies.remove(key);
  }

  public clear() {
    if (this.supportStorage) {
      return this.storage.clear();
    }
    // cookie clear 未实现
  }
}

然后我们分别实例化sessionStorage,localStorage

export const sessionStorageHelper = new StorageHelper(sessionStorage);

export const localStorageHelper = new StorageHelper(localStorage);

那么,我们外部直接调用地方,就切换为sessionStorageHelper和localStorageHelper,即可