QuotaExceededError The quota has been exceeded
程序员文章站
2022-03-29 19:05:58
...
(一)前言
我首先描述下,这种报错出现的场景
- ios <= 10 真机 Safari 的无痕浏览模式
- 使用localStorage or sessionStorage 的 setItem
当然,问题肯定社区有解决方案,以下链接可以满足你想要的答案
问题链接1
问题链接2
问题链接3
(二)解决过程
如果你看完,那么问题可以总结为,两个方向
- 是我们h5站点增加检测是否支持,并提示用户切换模式
- 我们在不支持情况,默认切到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,即可