Я сжал бинарный тест в этой функции, которую я использую:
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
по умолчанию равен 1 ГБ и ограничивает экспоненциальную скорость сканирования до начала двоичного поиска. Я сомневаюсь, что это даже нужно будет изменить, но я всегда думаю о будущем. ;)
На 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 байт).