web-dev-qa-db-fra.com

Quelle est la taille maximale des valeurs localStorage?

Étant donné que localStorage (actuellement) ne prend en charge que les chaînes en tant que valeurs, et pour ce faire, les objets doivent être hiérarchisés (stockés sous forme de chaîne JSON) avant de pouvoir être stockés, existe-t-il une limite définie concernant la longueur du fichier valeurs.

Est-ce que quelqu'un sait s'il existe une définition qui s'applique à tous les navigateurs?

480
Codekie

Citant le article de Wikipedia sur le stockage Web :

Le stockage Web peut être considéré de manière simpliste comme une amélioration des cookies, offrant une capacité de stockage beaucoup plus grande ( 10 Mo par origine dans Google Chrome ( https://plus.google.com/u/0/+ FrancoisBeaufort/posts/S5Q9HqDB8bh ), Mozilla Firefox et Opera, 10 Mo par zone de stockage dans Internet Explorer ) et de meilleures interfaces de programmation.

Et citant également un article de John Resig [publié en janvier 2007]:

Espace de stockage

Cela implique que, avec le stockage DOM, vous disposez de beaucoup plus d’espace de stockage que les limitations habituelles de l’agent utilisateur imposées aux cookies. Toutefois, le montant fourni n'est pas défini dans la spécification, ni diffusé de manière significative par l'agent utilisateur.

Si vous examinez le code source de Mozilla, vous constaterez que 5120 Ko correspond à la taille de stockage par défaut d'un domaine entier. Cela vous donne considérablement plus d'espace pour travailler avec un cookie typique de 2 Ko.

Cependant, la taille de cette zone de stockage peut être personnalisée par l'utilisateur (de sorte qu'une zone de stockage de 5 Mo n'est pas garantie, ni implicite) et l'utilisateur agent (Opera, par exemple, ne peut fournir que 3 Mo - mais seul le temps le dira.)

391
Daniel Vassallo

En fait, Opera n'a pas de limite de 5 Mo. Il offre d'augmenter la limite car les applications en demandent plus. L'utilisateur peut même choisir "Stockage illimité" pour un domaine.

Vous pouvez facilement testez les limites/quotas de stockage local vous-même.

122
Artemy Tregubenko

Voici un script simple pour connaître la limite:

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

Voici the Gist , JSFiddle et article de blog .

Le script testera la définition de chaînes de texte de plus en plus grandes jusqu'à ce que le navigateur lève une exception. À ce stade, les données de test sont effacées et une clé de taille est définie dans localStorage, stockant la taille en kilo-octets.

67
cdmckay

Navigateurs mobiles:

Browser    | Chrome    | Android Browser    | Firefox     | iOS Safari
Version    | 40        | 4.3                | 34          | 6-8
Available  | 10MB      | 2MB                | 10MB        | 5MB

Navigateurs de bureau:

Browser    | Chrome   | Opera    | Firefox    | Safari      | IE
Version    | 40       | 27       | 34         | 6-8         | 9-11
Available  | 10MB     | 10MB     | 10MB       | 5MB         | 10MB

lien de référence

29
Behnam Mohammadi

Recherchez la longueur maximale d'une chaîne pouvant être stockée dans localStorage

Cet extrait trouvera la longueur maximale d'une chaîne pouvant être stockée dans localStorage par domaine.

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

Notez que la longueur d'une chaîne est limitée en JavaScript; si vous souhaitez afficher la quantité maximale de données pouvant être stockée dans localStorage lorsqu'elle n'est pas limitée à une seule chaîne, vous pouvez utiliser le code de cette réponse .

Edit: Les extraits de pile ne supportent pas localStorage, donc voici un lien vers JSFiddle .

Résultats

Chrome (45.0.2454.101): 5242878 caractères
Firefox (40.0.1): 5242883 caractères
Internet Explorer (11.0.9600.18036) 16386122066 122070 caractères

Je reçois des résultats différents à chaque exécution dans Internet Explorer.

27
user2428118

Ne supposez pas que 5 Mo sont disponibles - la capacité de stockage local varie selon les navigateurs. 2,5 Mo, 5 Mo et illimité sont les valeurs les plus courantes. Source: http://dev-test.nemikor.com/web-storage/support-test/

24
tagawa

Vous ne souhaitez pas hiérarchiser les objets volumineux en une seule entrée localStorage. Ce serait très inefficace - le tout devrait être analysé et ré-encodé chaque fois que de petits détails changent. En outre, JSON ne peut pas gérer plusieurs références croisées au sein d'une structure d'objet et efface de nombreux détails, par exemple. le constructeur, les propriétés non numériques des tableaux, le contenu d'une entrée clairsemée, etc.

Au lieu de cela, vous pouvez utiliser Rhaboo . Il stocke des objets volumineux en utilisant de nombreuses entrées localStorage afin que vous puissiez apporter rapidement de petites modifications. Les objets restaurés sont des copies beaucoup plus précises des objets enregistrés et l’API est incroyablement simple. Par exemple.:

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

BTW, je l'ai écrit.

13
Adrian May

J'aime vraiment réponse de cdmckay , mais il n’est pas très beau de vérifier la taille en temps réel: c’est tout simplement trop lent (2 secondes pour moi). Il s’agit de la version améliorée, beaucoup plus rapide et précise, avec également la possibilité de choisir l’importance de l’erreur (par défaut, 250,000, plus l’erreur est petite, plus le calcul est long):

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

Tester:

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

Cela fonctionne beaucoup plus rapidement pour l'erreur standard; cela peut aussi être beaucoup plus précis si nécessaire.

6
smnbbrv

Vous pouvez utiliser le code suivant dans les navigateurs modernes pour vérifier efficacement le quota de stockage (total et utilisé) en temps réel:

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

Je fais ce qui suit:

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;
};
5
Itay Merchav

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 les tests, puis les restaure.

Comment ça marche: Il double la taille jusqu'à ce que la limite soit atteinte ou que le test échoue. Il enregistre 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 le succès); affûter dans la valeur appropriée.

upperLimit correspond à 1 Go par défaut et limite le nombre de fois où l'analyse doit être effectuée de manière exponentielle avant le début de 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).

4
James Wilkins

Une fois que j'ai développé Chrome (navigateur de bureau) extension et testé Stockage local taille réelle maximale pour cette raison.

Mes résultats:

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

Plus que 10240 KB usage m'a renvoyé l'erreur:

Uncaught DOMException: Impossible d'exécuter 'setItem' sur 'Storage': La définition de la valeur de 'notes' a dépassé le quota.

1
smokehill