Wat is de maximale grootte van localStorage-waarden?

Aangezien localStorage(momenteel) alleen strings als waarden ondersteunt, en om dat te doen, moeten de objecten worden gestringificeerd (opgeslagen als JSON-string) voordat ze kunnen worden opgeslagen, is er een gedefinieerde beperking met betrekking tot de lengte van de waarden.

Weet iemand of er een definitie is die voor alle browsers geldt?


Antwoord 1, autoriteit 100%

Citaat uit het Wikipedia-artikel over webopslag:

Webopslag kan eenvoudig worden gezien als een verbetering van cookies, die een veel grotere opslagcapaciteit biedt (10 MB per herkomst in Google Chrome(https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh), Mozilla Firefox en Opera; 10 MB per opslag gebied in Internet Explorer) en betere programmatische interfaces.

En ook een citaat uit een John Resig-artikel[gepost in januari 2007]:

Opslagruimte

Er wordt gesuggereerd dat, met DOM Storage,
je hebt aanzienlijk meer opslagruimte
ruimte dan de typische user-agent
beperkingen opgelegd aan cookies.
Echter, het bedrag dat wordt verstrekt
is niet gedefinieerd in de specificatie,
het wordt ook niet zinvol uitgezonden door
de user-agent.

Als je naar de Mozilla-broncode kijkt
we kunnen zien dat 5120 KB de standaard is
opslaggrootte voor een heel domein.
Hierdoor heb je aanzienlijk meer ruimte
om mee te werken dan een typische 2KB
koekje.

Echter, de grootte van deze opslagruimte
kan door de gebruiker worden aangepast
(dus a
5 MB opslagruimte is niet gegarandeerd,
het is ook niet geïmpliceerd) en de user-agent
(Opera mag bijvoorbeeld alleen bieden:
3 MB – maar de tijd zal het leren.)


Antwoord 2, autoriteit 30%

Eigenlijk heeft Opera geen limiet van 5 MB. Het biedt aan om de limiet te verhogen naarmate toepassingen meer vereisen. De gebruiker kan zelfs kiezen voor “Onbeperkte opslag” voor een domein.

Je kunt eenvoudig zelf localStorage-limieten/quotumtesten.


Antwoord 3, autoriteit 20%

Hier is een eenvoudig script om de limiet te achterhalen:

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);            
    }
}

Hier is de kern, JSFiddleen blog plaatsen.

Het script zal het instellen van steeds grotere tekstreeksen testen totdat de browser dit genereert en een uitzondering maakt. Op dat moment worden de testgegevens gewist en wordt een groottesleutel in localStorage ingesteld om de grootte in kilobytes op te slaan.


Antwoord 4, autoriteit 8%

Zoek de maximale lengte van een enkele tekenreeks die kan worden opgeslagen in localStorage

Dit fragment vindt de maximale lengte van een String die kan worden opgeslagen in localStorageper domein.

//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>

Houd er rekening mee dat de lengte van een string in JavaScript beperkt is; als u de maximale hoeveelheid gegevens wilt zien die kan worden opgeslagen in localStoragewanneer deze niet beperkt is tot een enkele tekenreeks, kan de code in dit antwoord gebruiken.

Bewerken:Stack Snippets ondersteunen geen localStorage, dus hier is een link naar JSFiddle.

Resultaten

Chrome (45.0.2454.101):5242878 tekens
Firefox (40.0.1):5242883 tekens
Internet Explorer (11.0.9600.18036): 16386122066122070 tekens

Ik krijg verschillende resultaten bij elke run in Internet Explorer.


Antwoord 5, autoriteit 6%

Ga er niet vanuit dat er 5 MB beschikbaar is – localOpslagcapaciteit verschilt per browser, waarbij 2,5 MB, 5 MB en onbeperkt de meest voorkomende waarden zijn.
Bron: http://dev-test.nemikor.com/web-storage/support-test/


Antwoord 6, autoriteit 4%

U wilt grote objecten niet samenvoegen tot een enkele localStorage-ingang. Dat zou erg inefficiënt zijn – het hele ding zou moeten worden geparseerd en opnieuw gecodeerd elke keer dat er een klein detail verandert. Ook kan JSON niet overweg met meerdere kruisverwijzingen binnen een objectstructuur en worden veel details weggevaagd, b.v. de constructor, niet-numerieke eigenschappen van arrays, wat er in een schaars item staat, enz.

In plaats daarvan kun je Rhaboogebruiken. Het slaat grote objecten op met behulp van veel localStorage-items, zodat u snel kleine wijzigingen kunt aanbrengen. De herstelde objecten zijn veel nauwkeuriger kopieën van de opgeslagen objecten en de API is ongelooflijk eenvoudig. Bijv.:

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');

Trouwens, ik heb het geschreven.


Antwoord 7, autoriteit 3%

Ik heb deze eenvoudige code geschreven die de localStorage-grootte in bytes test.

https://github.com/gkucmierz/Test-of-localStorage- limietquota

const check = bytes => {
  try {
    localStorage.clear();
    localStorage.setItem('a', '0'.repeat(bytes));
    localStorage.clear();
    return true;
  } catch(e) {
    localStorage.clear();
    return false;
  }
};

Github-pagina’s:

https://gkucmierz.github.io/Test-of-localStorage -limieten-quota/

Ik heb dezelfde resultaten op desktop chrome, opera, firefox, brave en mobile chrome, namelijk ~5Mbytes

voer hier de afbeeldingsbeschrijving in

En half kleiner resultaat in safari ~2Mbytes

voer hier de afbeeldingsbeschrijving in


Antwoord 8, autoriteit 2%

Ik heb een binaire test samengevat in deze functie die ik gebruik:

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)
}

Het maakt ook een back-up van de inhoud voordat het wordt getest, en herstelt ze vervolgens.

Hoe het werkt: het verdubbelt de grootte totdat de limiet is bereikt of de test mislukt. Het slaat dan de helft van de afstand tussen laag en hoog op en trekt elke keer de helft van de helft af (aftrekken bij mislukking en optellen bij succes); slijpen naar de juiste waarde.

upperLimitis standaard 1 GB en beperkt alleen hoe ver omhoog om exponentieel te scannen voordat de binaire zoekopdracht wordt gestart. Ik betwijfel of dit zelfs maar veranderd moet worden, maar ik denk altijd vooruit. 😉

In 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 en FireFox rapporteren ook dezelfde maximale grootte (10485762 bytes).


Antwoord 9

Ik doe het volgende:

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);
    maxLength = JSON.stringify(this.storageObject).length + maxLength + keyName.length - 2;
    return maxLength;
};

Antwoord 10

Ik vind het antwoord van cdmckay’s antwoorderg leuk, maar het ziet er niet echt goed uit om de grootte in realtime te controleren: is gewoon te traag (2 seconden voor mij). Dit is de verbeterde versie, die veel sneller en nauwkeuriger is, ook met een optie om te kiezen hoe groot de fout mag zijn (standaard 250,000, hoe kleiner de fout – hoe langer de berekening):

function getLocalStorageMaxSize(error) {
  if (localStorage) {
    var max = 10 * 1024 * 1024,
        i = 64,
        string1024 = '',
        string = '',
        // generate a random key
        testKey = 'size-test-' + Math.random().toString(),
        minimalFound = 0,
        error = error || 25e4;
    // fill a string with 1024 symbols / bytes    
    while (i--) string1024 += 1e16;
    i = max / 1024;
    // fill a string with 'max' amount of symbols / bytes    
    while (i--) string += string1024;
    i = max;
    // binary search implementation
    while (i > 1) {
      try {
        localStorage.setItem(testKey, string.substr(0, i));
        localStorage.removeItem(testKey);
        if (minimalFound < i - error) {
          minimalFound = i;
          i = i * 1.5;
        }
        else break;
      } catch (e) {
        localStorage.removeItem(testKey);
        i = minimalFound + (i - minimalFound) / 2;
      }
    }
    return minimalFound;
  }
}

Te testen:

console.log(getLocalStorageMaxSize()); // takes .3s
console.log(getLocalStorageMaxSize(.1)); // takes 2s, but way more exact

Dit werkt veel sneller voor de standaardfout; het kan ook veel nauwkeuriger zijn als dat nodig is.


Antwoord 11

U kunt de volgende code in moderne browsers gebruiken om het opslagquotum (totaal en gebruikt) efficiënt in realtime te controleren:

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);
            });
}

Antwoord 12

Eens heb ik de Chrome-extensie (desktopbrowser) ontwikkeld en om deze reden de werkelijke maximale grootte van Local Storage getest.

Mijn resultaten:

Ubuntu 18.04.1 LTS (64-bit)
Chrome 71.0.3578.98 (Official Build) (64-bit)
Local Storage content size 10240 KB (10 MB)

Meer dan 10240 KBgebruik gaf me de fout:

Ongevangen DOMException: kan ‘setItem’ niet uitvoeren op ‘Storage’: het instellen van de waarde van ‘notes’ heeft de quota overschreden.

Bewerken op 23 oktober 2020

Voor een Chrome-extensies beschikbare chrome.storageAPI. Als u de “opslag”-machtiging declareert in manifest.js:

{
    "name": "My extension",
    ...
    "permissions": ["storage"],
    ...
}

Je kunt het als volgt openen:

chrome.storage.local.QUOTA_BYTES // 5242880 (in bytes)

Other episodes