Qual é o tamanho máximo dos valores localStorage?

542

Como localStorage(atualmente) suporta apenas cadeias de caracteres como valores e, para fazer isso, os objetos precisam ser codificados (armazenados como cadeia de caracteres JSON) antes de poderem ser armazenados, existe uma limitação definida em relação ao comprimento dos valores.

Alguém sabe se existe uma definição que se aplica a todos os navegadores?

Codekie
fonte
15
Acho que ninguém respondeu à pergunta "comprimento máximo por valor".
Pete Alvin
@PeteAlvin Acabei de responder à pergunta .
user2428118
@PeteAlvin Alguém respondeu em 2015. As outras respostas abordam o limite do tamanho total, mas não o limite do tamanho por valor .
Ali

Respostas:

420

Citando o artigo da Wikipedia sobre Armazenamento na Web :

O armazenamento na Web pode ser visto de maneira simplista como uma melhoria nos cookies, fornecendo uma capacidade de armazenamento muito maior ( 10 MB por origem no Google Chrome ( https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh ), Mozilla Firefox e Opera; 10 MB por área de armazenamento no Internet Explorer ) e melhores interfaces programáticas.

E também citando um artigo de John Resig [publicado em janeiro de 2007]:

Espaço de armazenamento

Está implícito que, com o DOM Storage, você possui consideravelmente mais espaço de armazenamento do que as limitações típicas do agente do usuário impostas aos Cookies. No entanto, a quantidade fornecida não é definida na especificação, nem é transmitida de forma significativa pelo agente do usuário.

Se você olhar o código fonte da Mozilla, podemos ver que 5120KB é o tamanho de armazenamento padrão para um domínio inteiro. Isso oferece muito mais espaço para trabalhar do que um cookie típico de 2 KB.

No entanto, o tamanho dessa área de armazenamento pode ser personalizado pelo usuário (portanto, uma área de armazenamento de 5 MB não é garantida, nem está implícita) e o agente do usuário (Opera, por exemplo, pode fornecer apenas 3 MB - mas apenas o tempo dirá. )

Daniel Vassallo
fonte
28
@Cupidvogel não, significa que cada um domain( origin) pode armazenar 5 MB em qualquer cliente individual. Os dados são armazenados na máquina do cliente - de maneira alguma o localStoragemecanismo interage entre os clientes.
danielb
6
Não, eu só queria garantir que os mesmos dados sejam acessíveis em várias páginas para o mesmo domínio. Muitas vezes, acho que o domínio e a página das frases estão escritos como sinônimos, então só queria ter certeza!
Sexy Beast
9
Existe, no entanto, uma limitação em um único valor? (Se eu tenho um monte de bandeiras para loja, como é que é seguro para armazená-lo como JSON em uma única propriedade?)
phtrivier
5
Eu tenho Safari em 5MB e Chrome 39 a 10 MB (não tenho certeza quando ele foi impulsionado a partir de 5MB) Ver este artigo html5rocks.com/en/tutorials/offline/quota-research
Ally
18
@Cupidvogel: Não, é não por domínio, é de origem , como o termo é usado vis-a-vis a política de Origem Same e tal: Esquema + host + porta. http://example.come https://example.comnão são da mesma origem (esquemas diferentes). http://example.come http://www.example.comnão são da mesma origem (hosts diferentes). http://example.come http://example.com:8080não são da mesma origem (portas diferentes). HTH. :-)
TJ Crowder
134

Na verdade, o Opera não tem limite de 5 MB. Oferece aumentar o limite, pois os aplicativos exigem mais. O usuário pode até escolher "Armazenamento ilimitado" para um domínio.

Você pode testar facilmente os limites / cotas de armazenamento local .

Tom Adler
fonte
50
Não trava mais o Chrome ... Ponto interessante: 5 MB equivale a 2,5 milhões de caracteres no Chrome. Então, aparentemente, o UFT16 é usado para o localStore.
Felix Alcala
1
@FelixAlcala Infelizmente, ele travou o Chrome 15.0.874.54 beta no Mac OS X. Eu tive um acidente com 1.500.000 caracteres.
Ivan Vučica
Ele travou o chrome no meu dispositivo, também redefiniu o bckground, mas não surpreende, meu telefone tem tão pouca memória RAM que não consegue lidar com um estúpido FLASHLIGHT APP aberto enquanto o chrome está aberto.
Jack
6
@FelixAlcala - Na verdade, o JavaScript é exposto UCS-2. Embora seja semelhante a UFT16algumas diferenças muito importantes ... principalmente em torno do fato de que o UCS-2 é anterior à UFT.
Jeremy J Starcher
@FelixAlcala Você acha que exibir quantos caracteres e seu tamanho equivalente ao disco (por exemplo, 2.700K caracteres ~ = 5.274 KB) é uma boa idéia?
AJ Hsu
76

Aqui está um script simples para descobrir o 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);            
    }
}

Aqui está a essência , JSFiddle e postagem no blog .

O script testará a configuração de cadeias de texto cada vez maiores, até que o navegador gere uma exceção. Nesse ponto, ele limpará os dados de teste e definirá uma chave de tamanho no localStorage, armazenando o tamanho em kilobytes.

cdmckay
fonte
1
Solução legal. Encontrei este forro , o que você acha?
Brasofilo 16/10
2
@brasofilo Eu acho que um liner assume que você tem 5 MB e subtrai a quantidade que está sendo usada.
Cdmckay #
Ooook, tiro certo. O problema que estou enfrentando com o seu código não está sendo capaz de obter resultados corretos com a maneira correta de converter o tamanho em bytes para KB, MB, GB em Javascript ... estimado.
Brasofilo 16/10
1
melhorou o desempenho ea qualidade de esta resposta aqui
smnbbrv
É 2020 e esta resposta funciona perfeitamente no vanilla Chrome e Firefox no Win10, dando tamanho = 5000.
A. Chiesa
34

Encontre o comprimento máximo de uma única sequência que pode ser armazenada em localStorage

Esse trecho encontrará o comprimento máximo de uma String que pode ser armazenada localStoragepor domínio.

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

Observe que o comprimento de uma string é limitado em JavaScript; se você deseja visualizar a quantidade máxima de dados que podem ser armazenados localStoragequando não estiverem limitados a uma única sequência, use o código nesta resposta .

Edit: Snippets de pilha não suportam localStorage, então aqui está um link para o JSFiddle .

Resultados

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

Eu obtenho resultados diferentes em cada execução no Internet Explorer.

user2428118
fonte
1
Engraçado, mas seu teste simples interrompe meu sistema bastante poderoso quando eu testo no navegador Edge (no Win 10) após aproximadamente 1 minuto de execução. Portanto, não posso anexar novos dados aos seus resultados))
vatavale 24/02
33

Navegadores para celular:

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

Navegadores de desktop:

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

Link de referência

Behnam Mohammadi
fonte
6
De onde vêm os números?
MrD 28/02
23
@BehnamMohammadi você pode adicionar uma referência ao local onde você tem isso para a completude
Chris Lang
1
E nenhuma referência foi preenchida. Mas, para a posteridade, esses números mudam um pouco. Devemos atualizar isso, mais navegadores e as informações atuais.
Malavos
3
@ChrisLang adicionou o link
Behnam Mohammadi
1
@Malavos adicionou o link
Behnam Mohammadi
26

Não assuma que 5 MB estão disponíveis - a capacidade de armazenamento local varia de acordo com o navegador, sendo 2,5 MB, 5 MB e ilimitados os valores mais comuns. Fonte: http://dev-test.nemikor.com/web-storage/support-test/

tagawa
fonte
13

Você não deseja restringir objetos grandes em uma única entrada localStorage. Isso seria muito ineficiente - a coisa toda teria que ser analisada e recodificada toda vez que alguns pequenos detalhes mudarem. Além disso, o JSON não pode lidar com várias referências cruzadas em uma estrutura de objeto e apaga muitos detalhes, por exemplo, o construtor, propriedades não numéricas de matrizes, o que há em uma entrada esparsa etc.

Em vez disso, você pode usar o Rhaboo . Ele armazena objetos grandes usando muitas entradas localStorage, para que você possa fazer pequenas alterações rapidamente. Os objetos restaurados são cópias muito mais precisas dos salvos e a API é incrivelmente simples. Por exemplo:

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, eu escrevi.

Adrian May
fonte
1
Obrigado Martin. Você também pode conferir meu repo 'evon'. Agora é apenas um serializador e a tinta está muito molhada, mas é mais rápida que o rhaboo e igualmente versátil. O Rhaboo será convertido em breve para usá-lo internamente.
Adrian Maio
7
Útil, mas acho que isso não aborda a questão "Qual é o tamanho máximo do localStorage;" sua resposta pode ser melhorada, informando o que acontece quando essa biblioteca tenta armazenar algo além do limite de tamanho e como reagir a ele.
Chris Moschini
6

Estou fazendo o seguinte:

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;
};
Itay Merchav
fonte
5
Maroun Maroun: verifique a postagem novamente, o autor forneceu o código para verificar programaticamente o tamanho máximo do armazenamento local. Parece ser uma resposta válida e não outra pergunta.
Arend
Executar este código gera um erro "instrução de retorno ilegal" no Chrome, como do tempo da escrita
DrewT
6

Gosto muito da resposta do cdmckay , mas não parece bom verificar o tamanho em tempo real: é muito lento (2 segundos para mim). Esta é a versão aprimorada, que é muito mais rápida e exata, também com uma opção para escolher qual o tamanho do erro (padrão 250,000, o erro menor é - quanto maior o cálculo):

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

Testar:

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

Isso funciona muito mais rápido para o erro padrão; também pode ser muito mais exato quando necessário.

smnbbrv
fonte
6

Eu condensou um teste binário nesta função que eu uso:

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

Ele também faz o backup do conteúdo antes do teste e os restaura.

Como funciona: Dobra o tamanho até o limite ser atingido ou o teste falhar. Em seguida, ele armazena metade da distância entre baixa e alta e subtrai / adiciona metade da metade de cada vez (subtrai na falha e adiciona no sucesso); aprimorando o valor adequado.

upperLimité de 1 GB por padrão e apenas limita a velocidade de digitalização exponencial antes de iniciar a pesquisa binária. Duvido que isso precise ser alterado, mas estou sempre pensando no futuro. ;)

No 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 também relatam o mesmo tamanho máximo (10485762 bytes).

James Wilkins
fonte
1
(E não se esqueça de localStorage.Clear()antes e depois de seu teste
simonmysun
5

Você pode usar o seguinte código em navegadores modernos para verificar com eficiência a cota de armazenamento (total e usada) em tempo real:

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);
            });
}
Abhishek
fonte
Não funciona bem para o Chrome. Usage (in Bytes): 647 , Total Quota (in Bytes): 32901464711 Isso está errado: o tamanho total possível é realmente 10485762.
James Wilkins
1

Uma vez eu desenvolvi a extensão do Chrome (navegador de desktop) e testei o tamanho máximo real do armazenamento local por esse motivo.

Meus resultados:

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

Mais do que o 10240 KBuso me retornou o erro:

DOMException não capturado: falha ao executar 'setItem' em 'Armazenamento': a configuração do valor de 'notas' excedeu a cota.

fumaça
fonte
0

Eu escrevi esse código simples que está testando o tamanho do localStorage em bytes.

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

Páginas do Github:

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

Eu tenho os mesmos resultados em cromo para desktop, ópera, firefox, cromo corajoso e móvel que é ~ 5Mbytes

insira a descrição da imagem aqui

E metade do resultado menor no safari ~ 2Mbytes

insira a descrição da imagem aqui

gkucmierz
fonte