Qual è la dimensione massima dei valori localStorage?


542

Dal localStoragemomento che (attualmente) supporta solo stringhe come valori e per fare ciò gli oggetti devono essere stringiti (archiviati come stringa JSON) prima di poter essere archiviati, esiste una limitazione definita per quanto riguarda la lunghezza dei valori.

Qualcuno sa se esiste una definizione che si applica a tutti i browser?


15
Penso che nessuno abbia effettivamente risposto alla domanda "lunghezza massima per valore".
Pete Alvin,

@PeteAlvin Ho appena risposto alla domanda .
user2428118,


@PeteAlvin Qualcuno ha risposto nel 2015. Le altre risposte riguardano il limite sulla dimensione totale, ma non il limite sulla dimensione per valore .
Ali,

Risposte:


420

Citando l' articolo di Wikipedia su Web Storage :

L'archiviazione Web può essere vista in modo semplice come un miglioramento dei cookie, fornendo una capacità di archiviazione molto maggiore ( 10 MB per origine in Google Chrome ( https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh ), Mozilla Firefox e Opera; 10 MB per area di archiviazione in Internet Explorer ) e migliori interfacce programmatiche.

E anche citando un articolo di John Resig [pubblicato a gennaio 2007]:

Spazio di archiviazione

È implicito che, con DOM Storage, si disponga di uno spazio di archiviazione considerevolmente maggiore rispetto alle limitazioni tipiche dell'agente utente imposte ai cookie. Tuttavia, l'importo fornito non è definito nelle specifiche, né viene trasmesso in modo significativo dal programma utente.

Se osservi il codice sorgente di Mozilla, possiamo vedere che 5120 KB è la dimensione di archiviazione predefinita per un intero dominio. Questo ti dà molto più spazio su cui lavorare rispetto a un tipico cookie da 2 KB.

Tuttavia, le dimensioni di questa area di archiviazione possono essere personalizzate dall'utente (quindi un'area di archiviazione di 5 MB non è garantita, né è implicita) e l'agente utente (Opera, ad esempio, può fornire solo 3 MB, ma solo il tempo lo dirà. )


28
@Cupidvogel no, significa che ognuno domain( origin) può memorizzare 5 MB su ogni singolo client. I dati sono archiviati sul computer client, in nessun modo il localStoragemeccanismo interagisce tra i client.
Daniel B

6
No, volevo solo assicurarmi che gli stessi dati fossero accessibili su più pagine per lo stesso dominio. Spesso trovo il dominio delle frasi e la pagina spiegati come sinonimi, quindi volevo solo saperlo con certezza!
SexyBeast,

9
Esiste tuttavia una limitazione su un singolo valore? (Se ho molte bandiere da conservare, quanto è sicuro memorizzarlo come JSON in una singola proprietà?)
phtrivier

5
Ho Safari a 5 MB e Chrome 39 a 10 MB (non sono sicuro quando è stato potenziato da 5 MB) Vedi questo articolo html5rocks.com/en/tutorials/offline/quota-research
Ally

18
@Cupidvogel: No, non è per dominio, è per origine , in quanto il termine viene utilizzato di fronte alla stessa politica di origine e ad esempio: schema + host + porta. http://example.come https://example.comnon hanno la stessa origine (schemi diversi). http://example.come http://www.example.comnon sono la stessa origine (host diversi). http://example.come http://example.com:8080non hanno la stessa origine (porte diverse). HTH. :-)
TJ Crowder

134

In realtà Opera non ha un limite di 5 MB. Offre di aumentare il limite poiché le applicazioni richiedono di più. L'utente può anche scegliere "Spazio illimitato" per un dominio.

Puoi testare facilmente i limiti / le quote di LocalStorage .


50
Chrome non va più in crash ... Punto interessante: 5 MB equivalgono a 2,5 milioni di caratteri su Chrome. Quindi apparentemente, UFT16 è usato per localStore.
Felix Alcala,

1
@FelixAlcala Sfortunatamente, si blocca Chrome 15.0.874.54 beta su Mac OS X. Ho avuto un arresto a 1.500.000 caratteri.
Ivan Vučica,

Si è schiantato su Chrome sul mio dispositivo, anche azzerato il bckground, ma non sorpreso, il mio telefono ha così poca RAM, non può gestire una stupida APP FLASHLIGHT aperta mentre Chrome è aperto.
Jack,

6
@FelixAlcala - In realtà, JavaScript espone UCS-2. Mentre è simile UFT16ci sono alcune differenze molto importanti ... Per lo più ruotano attorno al fatto che UCS-2 precede UFT.
Jeremy J Starcher,

@FelixAlcala Pensi che sia una buona idea visualizzare quanti caratteri e l'equivalente delle dimensioni del disco (es. 2.700K caratteri ~ = 5.274 KB)?
AJ Hsu,

76

Ecco uno script semplice per scoprire il 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);            
    }
}

Ecco l'essenza , JSFiddle e il post sul blog .

Lo script testerà l'impostazione di stringhe di testo sempre più grandi fino a quando il browser non genererà eccezioni. A quel punto cancellerà i dati del test e imposterà una chiave di dimensione in localStorage memorizzando la dimensione in kilobyte.


1
Soluzione interessante. Ho trovato questa fodera , cosa ne pensi?
brasofilo,

2
@brasofilo Penso che un liner presupponga che tu abbia 5 MB e quindi sottrae l'importo utilizzato.
cdmckay,

Ooook, colpo sicuro. Il problema che sto riscontrando con il tuo codice non è riuscire a ottenere risultati corretti con il modo corretto di convertire le dimensioni in byte in KB, MB, GB in Javascript ... Lo rivedrò domani, ma se puoi dare un'occhiata, apprezzato.
brasofilo,

1
migliorato le prestazioni e la qualità di questa risposta qui
smnbbrv

È il 2020 e questa risposta funziona perfettamente sia su Chrome vanilla che su Firefox su Win10, dando dimensioni = 5000.
A. Chiesa,

34

Trova la lunghezza massima di una singola stringa che può essere archiviata localStorage

Questo frammento troverà la lunghezza massima di una stringa che può essere archiviata localStorageper dominio.

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

Si noti che la lunghezza di una stringa è limitata in JavaScript; se si desidera visualizzare la quantità massima di dati che è possibile archiviare localStoragequando non è limitata a una singola stringa, è possibile utilizzare il codice in questa risposta .

Modifica: I frammenti di stack non supportano localStorage, quindi ecco un link a JSFiddle .

risultati

Chrome (45.0.2454.101): 5242878 caratteri
Firefox (40.0.1): 5242883 caratteri
Internet Explorer (11.0.9600.18036) :16386 122066 122070 caratteri

Ottengo risultati diversi su ogni corsa in Internet Explorer.


1
Divertente, ma il tuo semplice test ha interrotto il mio sistema piuttosto potente quando provo nel browser Edge (su Win 10) dopo circa 1 minuto di esecuzione. Quindi non posso aggiungere nuovi dati ai tuoi risultati))
vatavale

33

Browser per dispositivi mobili:

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

Browser desktop:

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

Link di riferimento


6
Da dove vengono i numeri?
MrD

23
@BehnamMohammadi puoi aggiungere un riferimento a dove lo hai ottenuto per completezza
Chris Lang,

1
E nessun riferimento è mai stato inserito. Ma per i posteri, questi numeri cambiano un po '. Dovremmo aggiornare questo abbiamo più browser e le informazioni correnti.
Malavos,

3
@ChrisLang link aggiunto
Behnam Mohammadi

1
@Malavos aggiunto link
Behnam Mohammadi


13

Non si desidera stringere oggetti di grandi dimensioni in una singola voce localStorage. Sarebbe molto inefficiente: il tutto dovrebbe essere analizzato e ricodificato ogni volta che alcuni lievi cambiamenti di dettaglio. Inoltre, JSON non è in grado di gestire più riferimenti incrociati all'interno di una struttura di oggetti e cancella molti dettagli, ad esempio il costruttore, le proprietà non numeriche degli array, cosa c'è in una voce sparsa, ecc.

Invece, puoi usare Rhaboo . Memorizza oggetti di grandi dimensioni utilizzando molte voci localStorage in modo da poter apportare rapidamente piccole modifiche. Gli oggetti ripristinati sono copie molto più accurate di quelli salvati e l'API è incredibilmente semplice. Per esempio:

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

A proposito, l'ho scritto.


1
Grazie Martin. Potresti anche controllare il mio repository "evon". Al momento è solo un serializzatore e l'inchiostro è molto umido, ma è più veloce del rhaboo e altrettanto versatile. Rhaboo sarà presto convertito per usarlo internamente.
Adrian,

7
Utile ma non credo che questo risolva la domanda "Qual è la dimensione massima di localStorage;" la tua risposta potrebbe essere migliorata affermando cosa succede quando questa libreria tenta di archiviare qualcosa oltre il limite di dimensioni e come reagire ad essa.
Chris Moschini,

6

Sto facendo quanto segue:

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
Maroun Maroun: controlla di nuovo il post, l'autore ha fornito il codice per controllare programmaticamente la dimensione massima della memoria locale. Questa sembra essere una risposta valida e non un'altra domanda.
Arend

L'esecuzione di questo codice genera un errore "Dichiarazione di restituzione illegale" in Chrome, al momento della stesura di questo documento
DrewT

6

Mi piace molto la risposta di cdmckay , ma non sembra davvero bello controllare le dimensioni in tempo reale: è troppo lento (2 secondi per me). Questa è la versione migliorata, che è molto più veloce e più esatta, anche con un'opzione per scegliere quanto grande può essere l'errore (impostazione predefinita 250,000, l'errore più piccolo è - più lungo è il calcolo):

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

Testare:

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

Funziona molto più velocemente per l'errore standard; inoltre può essere molto più esatto quando necessario.


6

Ho condensato un test binario in questa funzione che utilizzo:

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

Esegue inoltre il backup dei contenuti prima del test, quindi li ripristina.

Come funziona: raddoppia la dimensione fino a raggiungere il limite o il test ha esito negativo. Memorizza quindi metà della distanza tra basso e alto e sottrae / aggiunge una metà della volta ogni volta (sottrai in caso di fallimento e aggiungi in caso di successo); affinando il valore corretto.

upperLimitè 1 GB per impostazione predefinita e limita semplicemente la scansione verso l'alto in modo esponenziale prima di avviare la ricerca binaria. Dubito che anche questo debba essere cambiato, ma penso sempre al futuro. ;)

Su 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 e FireFox riportano anche la stessa dimensione massima (10485762 byte).


1
(E non dimenticare di localStorage.Clear()prima e dopo i test
simonmysun,

5

È possibile utilizzare il codice seguente nei browser moderni per controllare in modo efficiente la quota di archiviazione (totale e utilizzata) in tempo reale:

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

Non funziona bene per Chrome. Usage (in Bytes): 647 , Total Quota (in Bytes): 32901464711 Questo è sbagliato: la dimensione totale possibile è in realtà 10485762.
James Wilkins

1

Una volta ho sviluppato l' estensione Chrome (browser desktop) e testato la dimensione massima reale dell'archiviazione locale per questo motivo.

I miei risultati:

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

Più 10240 KBdell'utilizzo mi ha restituito l'errore:

DOMException non rilevata: impossibile eseguire "setItem" su "Archiviazione": l'impostazione del valore di "note" ha superato la quota.


0

Ho scritto questo semplice codice che sta testando le dimensioni di localStorage in byte.

https://github.com/gkucmierz/Test-of-localStorage-limits-quota

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

Pagine di Github:

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

Ho gli stessi risultati su Chrome desktop, Opera, Firefox, Brave e Chrome portatile che è di ~ 5 MB

inserisci qui la descrizione dell'immagine

E metà risultato più piccolo in safari ~ 2Mbyte

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.