计算localStorage空间的使用情况

我正在使用Bespin编辑器和HTML5的localStorage创build一个应用程序。 它在本地存储所有文件,并帮助语法,使用JSLint和一些其他parsing器的CSS和HTML来帮助用户。

我想计算已经使用了多lesslocalStorage限制,实际上有多less。 今天这可能吗? 我正在考虑不要简单地计算存储的位。 但是,我再也不确定还有什么我不能衡量自己。

您可以通过使用JSON方法将整个localStorage对象转换为JSONstring来获得一个近似的想法:

JSON.stringify(localStorage).length 

我不知道字节精度会有多高,尤其是如果你使用额外的对象时,加上less量字节的增加标记,但是我认为比只考虑28K而不是280K(或者副标题)反之亦然)。

我没有find通用的方法来获得我需要的浏览器的剩余限制,但我确实发现,当您达到极限时,会popup一条错误消息。 这在每个浏览器中当然是不同的。

为了最大限度地使用这个小脚本:

 for (var i = 0, data = "m"; i < 40; i++) { try { localStorage.setItem("DATA", data); data = data + data; } catch(e) { var storageSize = Math.round(JSON.stringify(localStorage).length / 1024); console.log("LIMIT REACHED: (" + i + ") " + storageSize + "K"); console.log(e); break; } } localStorage.removeItem("DATA"); 

从那我得到这个信息:

谷歌浏览器

  • 抛出:DOMException:
    • 代码:22
    • 消息:“在'Storage'上执行'setItem'失败:设置'data'的值超过配额。
    • 名称:“QuotaExceededError”

火狐浏览器

  • 抛出:DOMException:
    • 代码:1014
    • 消息:“持久存储最大大小达到”
    • 名称:“NS_ERROR_DOM_QUOTA_REACHED”

苹果浏览器

  • 抛出:DOMException:
    • 代码:22
    • 消息:“QuotaExceededError:DOMexception22”
    • 名称:“QuotaExceededError”

Internet Explorer,Edge (社区)

  • 抛出:DOMException:
    • 代码:22
    • 消息:“QuotaExceededError”
    • 名称:“QuotaExceededError”

我的解决scheme

到目前为止我的解决scheme是添加一个额外的电话,每次用户将保存任何东西。 如果发现exception,我会告诉他们他们的存储容量已经不足了。


编辑:删除添加的数据

我忘了提到,为了实际工作,您需要删除最初设置的DATA项目。 上面通过使用removeItem()函数反映了更改。

为此,IE8实现了remainingSpace属性:

 alert(window.localStorage.remainingSpace); // should return 5000000 when empty 

不幸的是,这似乎不是在其他浏览器中可用。 但是我不确定他们是否实现了类似的东西。

您可以使用下面的行来准确计算这个值, 这里是一个jsfiddle来说明它的用法

 alert(1024 * 1024 * 5 - escape(encodeURIComponent(JSON.stringify(localStorage))).length); 

今天进行testing(超过存储配额),并提出了一个解决scheme。 国际海事组织知道限制是什么以及我们所处的位置远比实施一种function性的方式来继续存储超出配额的价值要小得多。

因此,不要尝试进行大小比较和容量检查,让我们在达到配额时做出反应,将当前存储量减less三分之一,然后重新存储。 如果减less失败,请停止储存。

 set: function( param, val ) { try{ localStorage.setItem( param, typeof value == 'object' ? JSON.stringify(value) : value ) localStorage.setItem( 'lastStore', new Date().getTime() ) } catch(e){ if( e.code === 22 ){ // we've hit our local storage limit! lets remove 1/3rd of the entries (hopefully chronologically) // and try again... If we fail to remove entries, lets silently give up console.log('Local storage capacity reached.') var maxLength = localStorage.length , reduceBy = ~~(maxLength / 3); for( var i = 0; i < reduceBy; i++ ){ if( localStorage.key(0) ){ localStorage.removeItem( localStorage.key(0) ); } else break; } if( localStorage.length < maxLength ){ console.log('Cache data reduced to fit new entries. (' + maxLength + ' => ' + localStorage.length + ')'); public.set( param, value ); } else { console.log('Could not reduce cache size. Removing session cache setting from this instance.'); public.set = function(){} } } } } 

这个函数存在于一个包装对象中,所以public.set只是简单地调用它自己。 现在我们可以join存储,不用担心配额是多less,或者我们有多接近。 如果一个商店超过三分之一的配额大小,这个function将停止剔除并退出存储,在这一点上,你不应该caching呢?

要添加到浏览器的testing结果:

火狐 i = 22。

我的Mac上的Safari 5.0.4版本没有挂起。 错误为Chrome。 I = 21。

Opera告诉用户网站想要存储数据,但没有足够的空间。 用户可以拒绝该请求,增加所需数量或其他限制的限制,或将其设置为无限制。 转到opera:webstorage来说明是否显示此消息。 I = 20。 抛出的错误与Chrome相同。

IE9标准模式错误如Chrome。 I = 22。

在IE8标准模式下的IE9控制台消息“错误:没有足够的存储可用于完成此操作”。 I = 22

IE9在旧模式下的对象错误。 I = 22。

IE8没有一个副本来testing,但支持本地存储(http://stackoverflow.com/questions/3452816/does-ie8-support-out-of-the-box-in-localstorage);

IE7及以下版本不支持本地存储。

您可以使用此Web存储支持testing来testing您的浏览器

我在我的android平板电脑和Windows笔记本电脑上testing了Firefox ,并在Windows上testing了结果:

  1. Firefox (窗口):

    • localStorage :5120k字符
    • sessionStorage :5120k字符
    • localStorage :*不支持
  2. Firefox (android):

    • localStorage :2560k字符
    • sessionStorage :无限(testing运行至10240k字符== 20480k字节)
    • localStorage不支持
  3. (窗户):

    • localStorage :5120k字符
    • sessionStorage :5120k字符
    • localStorage不支持

更新

在谷歌浏览器版本52.0.2743.116米(64位)限制在5101k字符稍低一点。 这意味着最大可用可能会在版本中更改。

希望我可以在评论中添加这个 – 没有足够的代表,对不起。

我跑了一些性能testing – 期望JSON.stringify(localStorage).length是一个昂贵的本地存储容量大的操作。

http://jsperf.com/occupied-localstorage-json-stringify-length

确实如此 – 跟踪你正在存储的东西的价格大约要高出50倍,并且让本地存储更加丰富。

这个function得到确切的存储/左:

我在这里为localStorage *做了一套有用的函数*

http://jsfiddle.net/kzq6jgqa/3/

 function getLeftStorageSize() { var itemBackup = localStorage.getItem(""); var increase = true; var data = "1"; var totalData = ""; var trytotalData = ""; while (true) { try { trytotalData = totalData + data; localStorage.setItem("", trytotalData); totalData = trytotalData; if (increase) data += data; } catch (e) { if (data.length < 2) break; increase = false; data = data.substr(data.length / 2); } } localStorage.setItem("", itemBackup); return totalData.length; } // Examples document.write("calculating.."); var storageLeft = getLeftStorageSize(); console.log(storageLeft); document.write(storageLeft + ""); // to get the maximum possible *clear* the storage localStorage.clear(); var storageMax = getLeftStorageSize(); 

请注意,这不是很快,所以不要一直使用它。

有了这个,我也发现:物品名称占用的空间与物品的长度相同,物品价值也会占用它们的长度。

我得到的最大存储量 – 大约5M:

  • 5000000个字符 – 边缘
  • 5242880字符 – Chrome
  • 5242880字符 – Firefox
  • 5000000个字符 – IE

您将在小提琴中find一些没有评论的代码,以查看控制台中的进度。

花了我一些时间,希望这有助于☺

我需要真正地模拟和testing我的模块在存满时所做的工作,所以我需要在存储空间满的时候精确地确定存储空间的大小,而不是接受的答案,这个答案会以i ^ 2的速度丢失。

这是我的脚本,当达到内存上限时,它应该始终产生10的精度,并且相当快,尽pipe有一些简单的优化…编辑:我更好,精确的脚本:

 function fillStorage() { var originalStr = "1010101010"; var unfold = function(str, times) { for(var i = 0; i < times; i++) str += str; return str; } var fold = function(str, times) { for(var i = 0; i < times; i++) { var mid = str.length/2; str = str.substr(0, mid); } return str; } var runningStr = originalStr; localStorage.setItem("filler", runningStr); while(true) { try { runningStr = unfold(runningStr, 1); console.log("unfolded str: ", runningStr.length) localStorage.setItem("filler", runningStr); } catch (err) { break; } } runningStr = fold(runningStr, 1); var linearFill = function (str1) { localStorage.setItem("filler", localStorage.getItem("filler") + str1); } //keep linear filling until running string is no more... while(true) { try { linearFill(runningStr) } catch (err) { runningStr = fold(runningStr, 1); console.log("folded str: ", runningStr.length) if(runningStr.length == 0) break; } } console.log("Final length: ", JSON.stringify(localStorage).length) } 

这可能有助于某人。 在chrome中可以要求用户允许在需要时使用更多的磁盘空间:

 // Request Quota (only for File System API) window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) { window.webkitRequestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler); }, function(e) { console.log('Error', e); }); 

有关详细信息,请访问https://developers.google.com/chrome/whitepapers/storage#asking_more

  try { var count = 100; var message = "LocalStorageIsNOTFull"; for (var i = 0; i <= count; count + 250) { message += message; localStorage.setItem("stringData", message); console.log(localStorage); console.log(count); } } catch (e) { console.log("Local Storage is full, Please empty data"); // fires When localstorage gets full // you can handle error here ot emply the local storage }