因为目前localStorage
只支持字符串类型的值,而为了实现这个,对象需要被转换成字符串(JSON-string)格式,然后才能进行存储。那么,关于值的长度是否有限制,是否有适用于所有浏览器的定义呢?
是否有人知道这个问题的答案?
因为目前localStorage
只支持字符串类型的值,而为了实现这个,对象需要被转换成字符串(JSON-string)格式,然后才能进行存储。那么,关于值的长度是否有限制,是否有适用于所有浏览器的定义呢?
是否有人知道这个问题的答案?
可以简单地将Web Storage视为Cookie的改进,提供了更大的存储容量(在Google Chrome(https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh)、Mozilla Firefox和Opera中每个来源10MB;在Internet Explorer中每个存储区域10MB)以及更好的编程接口。
还引用了John Resig的一篇文章(发布于2007年1月):
存储空间
DOM 存储提供的存储空间比 Cookie 的典型用户代理限制要大得多,但是规范中并没有定义提供的存储量,并且用户代理也没有明确说明。
如果查看 Mozilla 源代码,可以看到整个域的默认存储大小为 5120KB。这给了你比典型的 2KB cookie 更多的可用空间。
然而,该存储区域的大小可以由用户自定义(因此不能保证有 5MB 存储区域,也不意味着有),并且用户代理(例如 Opera 可能仅提供 3MB - 但只有时间才能告诉我们)。
localStorage
机制绝不会在不同客户端之间进行交互。 - DanielBhttp://example.com
与https://example.com
不是同一来源(协议不同),http://example.com
与http://www.example.com
也不是同一来源(主机名不同),http://example.com
与http://example.com:8080
也不是同一来源(端口号不同)。希望对你有所帮助。 :-) - T.J. Crowder实际上,Opera浏览器没有5MB的限制。它会根据应用程序需要增加存储量。用户甚至可以选择为域名提供“无限制的存储空间”。
您可以轻松地测试本地存储限制/配额。
UCS-2
。虽然它类似于UTF16
,但有一些非常重要的区别……主要围绕着UCS-2比UTF早的事实。 - Jeremy J Starcher这是一个简单的脚本,用于查找极限:
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>
localStorage
,因此这里是JSFiddle的链接。
我编写了这个简单的代码,用于测试以字节为单位的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/
我在桌面版Google Chrome、Opera、Firefox、Brave和移动版Chrome上获得了相同的结果,大约为10兆字节。
而在Safari中则达到了一半的大小,约为4兆字节。
不要将大型对象字符串化成单个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');
顺便说一下,这是我写的。
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()
。 - simonmysun你可以在现代浏览器中使用以下代码来实时高效地检查存储配额(总数和已用):
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);
});
}
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;
};