J'ai condensé un test binaire dans cette fonction que j'utilise:
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)
}
Il sauvegarde également le contenu avant le test, puis les restaure.
Fonctionnement: il double la taille jusqu'à ce que la limite soit atteinte ou que le test échoue. Il stocke ensuite la moitié de la distance entre le bas et le haut et soustrait / ajoute la moitié de la moitié à chaque fois (soustrayez en cas d'échec et ajoutez en cas de succès); affiner dans la valeur appropriée.
upperLimit
est de 1 Go par défaut, et limite la distance à parcourir de façon exponentielle avant de lancer la recherche binaire. Je doute que cela doive même être changé, mais je pense toujours à l'avenir. ;)
Sur 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 et FireFox signalent également la même taille maximale (10485762 octets).