localStorage 存满了怎么办?
先来几道面试题
1、a.meituan.com 和 b.meituan.com 这两个域能够共享同一个 localStorage 吗?
2、在 webview 中打开一个页面:i.meituan.com/home.html,点击一个按钮,调用 js 桥打开一个新的 webview:i.meituan.com/list.html,这两个分属不同 webview 的页面能共享同一个 localStorage 吗?
3、如果 localStorage 存满了,再往里存东西,或者要存的东西超过了剩余容量,会发生什么?
答案
1、同一个域名(document.domain)共享同一个 localStorage,a.meituan.com 和 b.meituan.com 是两个域名,所以不能共享
2、能。相当于同一个浏览器的不同标签页。不同浏览器之间不能共享。
3、存不进去并报错(QuotaExceededError)
理想的方案
假设我们回到起点,从零建设前端工程,我们怎么避免 localStorage 存满的问题?
1、划分域名。各域名下的存储空间由各业务组统一规划使用
2、跨页面传数据:考虑单页应用、优先采用 url 传数据
3、最后的兜底方案:清掉别人的存储
互相伤害其实是个好办法
在已然发展很久的业务中,我们怎么解决此问题呢?
const QUOTA_EXCEEDED_ERR_CODE = 22 function write (key, data) { try { localStorage.setItem(key, data); } catch (e) { if (e.code === QUOTA_EXCEEDED_ERR_CODE) { localStorage.clear(); localStorage.setItem(key, data); } } }
上面这个方法还是有点问题,因为它把自己业务要用的东西也给删了,所以自己的业务最好统一在 key 上加一个前缀,清空 localStorage 时只删别人的。
有的同学可能会担心,这样会不会对其它业务造成伤害?或者产生一些难以发现的 bug。其实这种担心很大程度上是因为忽略了实际的使用场景。用户用同一个设备打开同一个 app,在同一个时间只能访问一个业务,因此不会存在某个业务正在使用过程中,localStorage 被其它业务清掉的场景,除非!除非有交叉的业务场景。
一、如何得到localStorage已使用容量
(function(){ if(!window.localStorage) { console.log('浏览器不支持localStorage'); } var size = 0; for(item in window.localStorage) { if(window.localStorage.hasOwnProperty(item)) { size += window.localStorage.getItem(item).length; } } console.log('当前localStorage已使用容量为' + (size / 1024).toFixed(2) + 'KB'); })()
二、如何获取localStorage最大容量
通过上面的分析,其实思路基本是一样的,都是通过字符长度来判断。
(function() { if(!window.localStorage) { console.log('当前浏览器不支持localStorage!') } var test = '0123456789'; var add = function(num) { num += num; if(num.length == 10240) { test = num; return; } add(num); } add(test); var sum = test; var show = setInterval(function(){ sum += test; try { window.localStorage.removeItem('test'); window.localStorage.setItem('test', sum); console.log(sum.length / 1024 + 'KB'); } catch(e) { console.log(sum.length / 1024 + 'KB超出最大限制'); clearInterval(show); } }, 0.5) })()
注:上面代码可能卡死浏览器
相关链接:
https://www.cnblogs.com/kidney/p/9058352.html
https://www.cnblogs.com/MonkeyKingK/p/5499831.html