Saya telah menyingkat tes biner ke fungsi ini yang saya gunakan:
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)
}
Itu juga mencadangkan konten sebelum pengujian, kemudian mengembalikannya.
Cara kerjanya: Ini menggandakan ukuran sampai batas tercapai atau tes gagal. Kemudian menyimpan setengah jarak antara rendah dan tinggi dan mengurangi / menambah setengah dari setiap kali (kurangi pada kegagalan dan tambahkan pada keberhasilan); mengasah ke nilai yang tepat.
upperLimit
adalah 1GB secara default, dan hanya membatasi seberapa jauh untuk memindai secara eksponensial sebelum memulai pencarian biner. Saya ragu ini bahkan perlu diubah, tapi saya selalu berpikir ke depan. ;)
Di 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, dan FireFox juga melaporkan ukuran maks yang sama (10485762 bytes).