Ich habe einen Binärtest in diese Funktion zusammengefasst, die ich verwende:
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)
}
Außerdem wird der Inhalt vor dem Testen gesichert und anschließend wiederhergestellt.
So funktioniert es: Es verdoppelt die Größe, bis das Limit erreicht ist oder der Test fehlschlägt. Es speichert dann die Hälfte des Abstandes zwischen niedrig und hoch und subtrahiert / addiert jedes Mal die Hälfte der Hälfte (subtrahiert bei Misserfolg und addiert Erfolg); Honen in den richtigen Wert.
upperLimit
ist standardmäßig 1 GB groß und begrenzt nur, wie weit nach oben exponentiell gescannt werden soll, bevor die binäre Suche gestartet wird. Ich bezweifle, dass dies überhaupt geändert werden muss, aber ich denke immer voraus. ;)
Auf 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 und FireFox melden ebenfalls dieselbe maximale Größe (10485762 Byte).