localStorage值的最大大小是多少?

由于localStorage(目前)只支持字符串作为值,为了做到这一点,对象需要在存储之前进行字符串化(存储为JSON-string),对于值的长度是否有一个定义的限制。

有人知道是否有一个适用于所有浏览器的定义吗?

528614 次浏览

引用维基百科关于网络存储的文章:

Web存储可以简单地看作是对cookie的改进,提供了更大的存储容量(10 MB每个起源谷歌Chrome(https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh), Mozilla Firefox和Opera;Internet Explorer浏览器下每个存储区域为10mb)和更好的编程接口。

我还引用了John Resig文章[2007年1月发布]的一句话:

存储空间

这意味着,使用DOM存储, 你有更大的存储空间 空间大于典型的用户代理 对cookie施加的限制。 然而,所提供的数量 在规范中没有定义, 它也没有被有意义的广播

.用户代理

如果你看Mozilla源代码 我们可以看到5120KB是默认值 整个域的存储大小。 这给了你相当大的空间 而不是典型的2KB 饼干。< / p >

然而,该存储区域的大小 可以由用户自定义(那么a 不保证5MB的存储空间, 这也不是隐含的)和用户代理 (例如,Opera可能只提供 3MB -但只有时间会告诉我们)

实际上Opera没有5MB的限制。它提供了增加限制的应用程序需要更多。用户甚至可以为一个域选择“无限存储”。

你可以自己轻松地test local存储限制/配额

不要认为5MB是可用的- local存储容量因浏览器而异,2.5MB, 5MB和无限是最常见的值。 来源:# EYZ0 < / p >

我正在做以下事情:

getLocalStorageSizeLimit = function () {


var maxLength = Math.pow(2,24);
var preLength = 0;
var hugeString = "0";
var testString;
var keyName = "testingLengthKey";


//2^24 = 16777216 should be enough to all browsers
testString = (new Array(Math.pow(2, 24))).join("X");


while (maxLength !== preLength) {
try  {
localStorage.setItem(keyName, testString);


preLength = testString.length;
maxLength = Math.ceil(preLength + ((hugeString.length - preLength) / 2));


testString = hugeString.substr(0, maxLength);
} catch (e) {
hugeString = testString;


maxLength = Math.floor(testString.length - (testString.length - preLength) / 2);
testString = hugeString.substr(0, maxLength);
}
}


localStorage.removeItem(keyName);


// Original used this.storageObject in place of localStorage.  I can only guess the goal is to check the size of the localStorage with everything but the testString given that maxLength is then added.
maxLength = JSON.stringify(localStorage).length + maxLength + keyName.length - 2;


return maxLength;
};

这里有一个简单的脚本来找出限制:

if (localStorage && !localStorage.getItem('size')) {
var i = 0;
try {
// Test up to 10 MB
for (i = 250; i <= 10000; i += 250) {
localStorage.setItem('test', new Array((i * 1024) + 1).join('a'));
}
} catch (e) {
localStorage.removeItem('test');
localStorage.setItem('size', i - 250);
}
}

这里是要点JSFiddle博客

该脚本将测试设置越来越大的文本字符串,直到浏览器抛出一个异常。这时,它将清除测试数据,并在localStorage中设置一个大小键,以千字节为单位存储大小。

您不希望将大对象字符串化到单个localStorage条目中。这将是非常低效的——每次有细微的细节变化时,整个东西都必须被解析和重新编码。此外,JSON不能在对象结构中处理多个交叉引用,并且删除了许多细节,例如构造函数、数组的非数值属性、稀疏条目中的内容等。

相反,您可以使用Rhaboo。它使用大量的localStorage条目来存储大型对象,因此您可以快速地进行小的更改。恢复的对象是保存的对象的更准确的副本,API非常简单。例如:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
one: ['man', 'went'],
2: 'mow',
went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

顺便说一句,这是我写的。

找出可以存储在localStorage中的单个字符串的最大长度

这个代码片段将找到每个域可以存储在localStorage中的String的最大长度。

//Clear localStorage
for (var item in localStorage) delete localStorage[item];


window.result = window.result || document.getElementById('result');


result.textContent = 'Test running…';


//Start test
//Defer running so DOM can be updated with "test running" message
setTimeout(function () {


//Variables
var low = 0,
high = 2e9,
half;


//Two billion may be a little low as a starting point, so increase if necessary
while (canStore(high)) high *= 2;




//Keep refining until low and high are equal
while (low !== high) {
half = Math.floor((high - low) / 2 + low);


//Check if we can't scale down any further
if (low === half || high === half) {
console.info(low, high, half);
//Set low to the maximum possible amount that can be stored
low = canStore(high) ? high : low;
high = low;
break;
}




//Check if the maximum storage is no higher than half
if (storageMaxBetween(low, half)) {
high = half;
//The only other possibility is that it's higher than half but not higher than "high"
} else {
low = half + 1;
}


}


//Show the result we found!
result.innerHTML = 'The maximum length of a string that can be stored in localStorage is <strong>' + low + '</strong> characters.';


//Functions
function canStore(strLen) {
try {
delete localStorage.foo;
localStorage.foo = Array(strLen + 1).join('A');
return true;
} catch (ex) {
return false;
}
}




function storageMaxBetween(low, high) {
return canStore(low) && !canStore(high);
}


}, 0);
<h1>LocalStorage single value max length test</h1>


<div id='result'>Please enable JavaScript</div>

请注意,在JavaScript中字符串的长度是有限的;如果您想查看localStorage中可以存储的最大数据量(不限于单个字符串),请使用这个答案可以用代码吗

编辑:堆栈片段不支持localStorage,所以是这里是JSFiddle的链接

结果

铬(45.0.2454.101): 5242878字符
Firefox (40.0.1): 5242883字符
Internet Explorer (11.0.9600.18036): 16386 122066 122070个字符

每次在Internet Explorer中运行都会得到不同的结果。

我真的很喜欢cdmckay的回答,但是它看起来不太好,实时检查大小:它太慢了(对我来说2秒)。这是一个改进的版本,它更快,更准确,也有一个选项来选择误差有多大(默认250,000,误差越小-计算时间越长):

function getLocalStorageMaxSize(error) {
if (localStorage) {
var max = 10 * 1024 * 1024,
i = 64,
string1024 = '',
string = '',
// generate a random key
testKey = 'size-test-' + Math.random().toString(),
minimalFound = 0,
error = error || 25e4;


// fill a string with 1024 symbols / bytes
while (i--) string1024 += 1e16;


i = max / 1024;


// fill a string with 'max' amount of symbols / bytes
while (i--) string += string1024;


i = max;


// binary search implementation
while (i > 1) {
try {
localStorage.setItem(testKey, string.substr(0, i));
localStorage.removeItem(testKey);


if (minimalFound < i - error) {
minimalFound = i;
i = i * 1.5;
}
else break;
} catch (e) {
localStorage.removeItem(testKey);
i = minimalFound + (i - minimalFound) / 2;
}
}


return minimalFound;
}
}

测试:

console.log(getLocalStorageMaxSize()); // takes .3s
console.log(getLocalStorageMaxSize(.1)); // takes 2s, but way more exact

对于标准错误,这工作得快得多;而且,在必要的时候,它可以更加精确。

您可以在现代浏览器中使用以下代码来有效地检查存储配额(total &实时使用):

if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate()
.then(estimate => {
console.log("Usage (in Bytes): ", estimate.usage,
",  Total Quota (in Bytes): ", estimate.quota);
});
}

我将二进制测试压缩到我使用的这个函数中:

function getStorageTotalSize(upperLimit/*in bytes*/) {
var store = localStorage, testkey = "$_test"; // (NOTE: Test key is part of the storage!!! It should also be an even number of characters)
var test = function (_size) { try { store.removeItem(testkey); store.setItem(testkey, new Array(_size + 1).join('0')); } catch (_ex) { return false; } return true; }
var backup = {};
for (var i = 0, n = store.length; i < n; ++i) backup[store.key(i)] = store.getItem(store.key(i));
store.clear(); // (you could iterate over the items and backup first then restore later)
var low = 0, high = 1, _upperLimit = (upperLimit || 1024 * 1024 * 1024) / 2, upperTest = true;
while ((upperTest = test(high)) && high < _upperLimit) { low = high; high *= 2; }
if (!upperTest) {
var half = ~~((high - low + 1) / 2); // (~~ is a faster Math.floor())
high -= half;
while (half > 0) high += (half = ~~(half / 2)) * (test(high) ? 1 : -1);
high = testkey.length + high;
}
if (high > _upperLimit) high = _upperLimit;
store.removeItem(testkey);
for (var p in backup) store.setItem(p, backup[p]);
return high * 2; // (*2 because of Unicode storage)
}

它还在测试之前备份内容,然后恢复它们。

它的工作原理:它将大小增加一倍,直到达到限制或测试失败。然后它存储低和高之间的距离的一半,并每次减去/增加一半(失败时减去,成功时增加);磨炼成合适的值。

upperLimit默认为1GB,只是限制在开始二分查找之前向上指数扫描的距离。我怀疑这种情况是否需要改变,但我总是未雨绸缪。;)

铬:

> getStorageTotalSize();
> 10485762
> 10485762/2
> 5242881
> localStorage.setItem("a", new Array(5242880).join("0")) // works
> localStorage.setItem("a", new Array(5242881).join("0")) // fails ('a' takes one spot [2 bytes])

IE11、Edge和FireFox也报告了相同的最大大小(10485762字节)。

曾经我开发了Chrome(桌面浏览器)扩展,并为此测试了本地存储的实际最大大小。

我的结果:

Ubuntu 18.04.1 LTS (64-bit)
Chrome 71.0.3578.98 (Official Build) (64-bit)
Local Storage content size 10240 KB (10 MB)

超过10240 KB使用返回我的错误:

Uncaught DOMException: Failed to execute 'setItem' on 'Storage':设置'notes'的值超过配额。

2020年10月23日编辑

对于Chrome扩展可用的chrome.storage API。如果你申报“仓储”;manifest.js中的权限:

{
"name": "My extension",
...
"permissions": ["storage"],
...
}

你可以像这样访问它:

chrome.storage.local.QUOTA_BYTES // 5242880 (in bytes)

我编写了这段简单的代码,以字节为单位测试localStorage大小。

https://github.com/gkucmierz/Test-of-localStorage-limits-quota

const check = bytes => {
try {
localStorage.clear();
localStorage.setItem('a', '0'.repeat(bytes));
localStorage.clear();
return true;
} catch(e) {
localStorage.clear();
return false;
}
};

Github页面:

< a href = " https://gkucmierz.github。io/Test-of-localStorage-limits-quota/" rel="nofollow noreferrer">https://gkucmierz.github.io/Test-of-localStorage-limits-quota/ .io/Test-of-localStorage-limits-quota/ " rel="nofollow noreferrer">https://gkucmierz.github.io/Test-of-localStorage-limits-quota/

我在桌面谷歌chrome, opera, firefox, brave和移动chrome上有相同的结果,这是~10Mbytes

enter image description here

和一半小的结果safari约4mb

enter image description here