以来 localStorage
(当前)仅支持将字符串用作值,并且为了做到这一点,需要先对对象进行字符串化(存储为JSON-string),然后才能存储它们,因此对值的长度存在定义的限制。
有谁知道是否存在适用于所有浏览器的定义?
以来 localStorage
(当前)仅支持将字符串用作值,并且为了做到这一点,需要先对对象进行字符串化(存储为JSON-string),然后才能存储它们,因此对值的长度存在定义的限制。
有谁知道是否存在适用于所有浏览器的定义?
Answers:
可以简单地将网络存储视为Cookie的一种改进,它提供了更大的存储容量(Google Chrome中每个原始站点10 MB(https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh),Mozilla Firefox和Opera;在Internet Explorer中每个存储区10 MB)和更好的编程界面。
并且引用了John Resig的文章 [发布于2007年1月]:
储存空间
暗示,使用DOM存储,您具有比对Cookie施加的典型用户代理限制更大的存储空间。但是,提供的数量没有在规范中定义,用户代理也没有有意义地广播。
如果查看Mozilla源代码,我们可以看到5120KB是整个域的默认存储大小。与典型的2KB Cookie相比,这为您提供了更多的处理空间。
但是,该存储区的大小可以由用户自定义(因此,不能保证5MB的存储区,也没有暗示),并且用户代理(例如,Opera只能提供3MB的存储空间,但是只有时间能说明问题)。 )
domain
(origin
)可以在任何单个客户端上存储5MB。数据存储在客户端计算机上-该localStorage
机制绝不会在客户端之间进行交互。
http://example.com
并且https://example.com
来源不同(方案不同)。http://example.com
并且http://www.example.com
不是同一来源(不同的主机)。http://example.com
并且http://example.com:8080
来源不同(端口不同)。HTH。:-)
实际上,Opera没有5MB的限制。随着应用程序需求的增加,它提供了增加限制的功能。用户甚至可以为域选择“无限存储”。
您可以轻松地自己测试localStorage限制/配额。
UCS-2
。尽管它类似于,UFT16
但还是有一些非常重要的区别……主要围绕UCS-2早于UFT的事实。
这是找出限制的简单脚本:
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);
}
}
该脚本将测试设置越来越大的文本字符串,直到浏览器抛出异常为止。到那时,它将清除测试数据,并在localStorage中设置一个大小密钥,以千字节为单位存储大小。
localStorage
此代码段将查找可以在localStorage
每个域中存储的字符串的最大长度。
//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的链接。
Chrome(45.0.2454.101): 5242878个字符
Firefox(40.0.1): 5242883个字符
Internet Explorer(11.0.9600.18036):16386 122066 122070个字符
在Internet Explorer中,每次运行都会得到不同的结果。
Browser | Chrome | Android Browser | Firefox | iOS Safari
Version | 40 | 4.3 | 34 | 6-8
Available | 10MB | 2MB | 10MB | 5MB
Browser | Chrome | Opera | Firefox | Safari | IE
Version | 40 | 27 | 34 | 6-8 | 9-11
Available | 10MB | 10MB | 10MB | 5MB | 10MB
不要假设5MB可用-本地存储容量会因浏览器而异,其中2.5MB,5MB和无限制是最常见的值。来源:http://dev-test.nemikor.com/web-storage/support-test/
您不想将大对象分成单个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');
顺便说一句,我写的。
我正在执行以下操作:
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);
maxLength = JSON.stringify(this.storageObject).length + maxLength + keyName.length - 2;
return maxLength;
};
我真的很喜欢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
对于标准错误,这可以更快地工作。必要时也可以更加精确。
我已经将二进制测试压缩到我使用的此函数中:
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,并且仅限制在开始二进制搜索之前向上扫描的指数范围。我怀疑这甚至需要更改,但是我一直在思考。;)
在Chrome上:
> 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字节)。
localStorage.Clear()
测试之前和之后
您可以在现代浏览器中使用以下代码来实时高效地检查存储配额(总计和已用):
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);
});
}
Usage (in Bytes): 647 , Total Quota (in Bytes): 32901464711
这是错误的:总规模可能实际上是10485762.
我写了这个简单的代码,以字节为单位测试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页面:
https://gkucmierz.github.io/Test-of-localStorage-limits-quota/
我在台式机Chrome,Opera,Firefox,Brave和Mobile chrome上的结果相同,约为5Mbytes
Safari的一半小结果〜2Mbytes