Pergunta

Estou criando um aplicativo usando o Editor Bespin e o LocalSorage do HTML5. Ele armazena todos os arquivos localmente e ajuda na gramática, usa o JSLINT e alguns outros analisadores para CSS e HTML para ajudar o usuário.

Quero calcular quanto do limite de armazenamento local foi usado e quanto há realmente. Isso é possível hoje? Eu estava pensando em não simplesmente calcular os bits que são armazenados. Mas, novamente, não tenho certeza do que mais existe que não posso me medir.

Foi útil?

Solução 2

Não encontrei uma maneira universal de obter o limite restante dos navegadores que eu precisava, mas descobri que, quando você atinge o limite, há uma mensagem de erro que aparece. Isso é de curso diferente em cada navegador.

Para maximizar, usei este pequeno script:

for (var i = 0, data = "m"; i < 40; i++) {
    try { 
        localStorage.setItem("DATA", data);
        data = data + data;
    } catch(e) {
        var storageSize = Math.round(JSON.stringify(localStorage).length / 1024);
        console.log("LIMIT REACHED: (" + i + ") " + storageSize + "K");
        console.log(e);
        break;
    }
}
localStorage.removeItem("DATA");

Daquele eu recebi esta informação:

Google Chrome

  • Domexception:
    • Código: 22
    • Mensagem: "Falha ao executar 'setItem' em 'armazenamento': definir o valor de 'dados' excedeu a cota".
    • Nome: "QuotAexcededError"

Mozilla Firefox

  • Domexception:
    • Código: 1014
    • Mensagem: "Tamanho máximo de armazenamento persistente alcançado"
    • Nome: "ns_error_dom_quota_reached"

Safári

  • Domexception:
    • Código: 22
    • Mensagem: "QuotaExcededError: DOM Exceção 22"
    • Nome: "QuotAexcededError"

Internet Explorer, Edge (comunidade)

  • Domexception:
    • Código: 22
    • Mensagem: "QuotaExcededError"
    • Nome: "QuotAexcededError"

Minha solução

Até agora, minha solução é adicionar uma chamada extra cada vez que o usuário salvaria qualquer coisa. E se a exceção for capturada, eu diria a eles que eles estão ficando sem capacidade de armazenamento.


Editar: exclua os dados adicionados

Esqueci de mencionar que, para que isso realmente funcione, você precisaria excluir o DATA item que foi definido originalmente. A mudança é refletida acima usando o remover item() função.

Outras dicas

Você pode ter uma idéia aproximada usando os métodos JSON para transformar todo o objeto LocalStorage para uma string json:

JSON.stringify(localStorage).length

Não sei como seria preciso, especialmente com os poucos bytes de marcação adicional se você estiver usando objetos adicionais- mas acho que é melhor do que pensar que você está apenas empurrando 28k e, em vez disso, fazendo 280k (ou vice- versa).

IE8 implementa o remainingSpace propriedade para esse fim:

alert(window.localStorage.remainingSpace);  // should return 5000000 when empty

Infelizmente, parece que isso não está disponível nos outros navegadores. No entanto, não tenho certeza se eles implementam algo semelhante.

Você pode usar a linha abaixo para calcular com precisão este valor e Aqui está um jsfiddle Para ilustração de seu uso

alert(1024 * 1024 * 5 - escape(encodeURIComponent(JSON.stringify(localStorage))).length);

Tornou -se hoje durante o teste (excedendo a cota de armazenamento) e criou uma solução. IMO, sabendo qual é o limite e onde estamos em relação é muito menos valioso do que implementar uma maneira funcional de continuar armazenando além da cota.

Assim, em vez de tentar fazer comparações de tamanho e verificações de capacidade, vamos reagir quando atingirmos a cota, reduzir nosso armazenamento atual em um terceiro e retomar o armazenamento. Se a referida redução falhar, pare de armazenar.

set: function( param, val ) { 
    try{
        localStorage.setItem( param, typeof value == 'object' ? JSON.stringify(value) : value )
        localStorage.setItem( 'lastStore', new Date().getTime() )
    }
    catch(e){
      if( e.code === 22 ){
        // we've hit our local storage limit! lets remove 1/3rd of the entries (hopefully chronologically)
        // and try again... If we fail to remove entries, lets silently give up
        console.log('Local storage capacity reached.')

        var maxLength = localStorage.length
          , reduceBy = ~~(maxLength / 3);

        for( var i = 0; i < reduceBy; i++ ){
          if( localStorage.key(0) ){
            localStorage.removeItem( localStorage.key(0) );
          }
          else break;
        }

        if( localStorage.length < maxLength ){
          console.log('Cache data reduced to fit new entries. (' + maxLength + ' => ' + localStorage.length + ')');
          public.set( param, value );
        }
        else {
          console.log('Could not reduce cache size. Removing session cache setting from this instance.');
          public.set = function(){}
        }
      }
    }
}

Essa função vive dentro de um objeto de wrapper, então público. O conjunto simplesmente se chama. Agora, podemos adicionar ao armazenamento e não nos preocupar o que é a cota ou o quão perto também estamos. Se uma única loja estiver excedendo 1/3, o tamanho da cota é onde essa função parará de abater e parar de armazenar e, nesse ponto, você não deve estar em cache de qualquer maneira, certo?

Para adicionar aos resultados dos testes do navegador:

Raposa de fogoi = 22.

SafáriA versão 5.0.4 no meu Mac não pendurou. Erro como Chrome. i = 21.

ÓperaDiz ao usuário que o site deseja armazenar dados, mas não tem espaço suficiente. O usuário pode rejeitar a solicitação, aumentar o limite para o valor necessário ou para vários outros limites ou defini -lo como ilimitado. Vá para Opera: WebStorage para dizer se essa mensagem aparece ou não. i = 20. O erro lançado é o mesmo que o Chrome.

IE9 Modo de padrõesErro como Chrome. i = 22.

IE9 no modo de padrões IE8Mensagem do console "Erro: não há armazenamento suficiente para concluir esta operação". i = 22

IE9 em modos mais antigoserro de objeto. i = 22.

Ie8Não tenha uma cópia para testar, mas o armazenamento local é suportado (http://stackoverflow.com/questions/3452816/does-ie8-support-to-of-the-box-in-localstorage)

IE7 e abaixoNão suporta armazenamento local.

Você pode testar seu navegador com isso Teste de suporte de armazenamento na Web

eu testei Raposa de fogo no meu tablet Android e no laptop do Windows e Cromo Apenas nos resultados do Windows:

  1. Raposa de fogo(janelas):

    • LocalStorage: 5120k char
    • SessionStorage: 5120k char
    • LocalStorage: *não suportado
  2. Raposa de fogo(Android):

    • LocalStorage: 2560k char
    • SessionStorage: Ilimitado (exatamente o teste é executado até 10240k char == 20480K byte)
    • LocalStorage: não suportado
  3. Cromo(janelas):

    • LocalStorage: 5120k char
    • SessionStorage: 5120k char
    • LocalStorage: não suportado

Atualizar

No Google Chrome, versão 52.0.2743.116 m (64 bits) limites onde um pouco menor em 5101k personagens. Isso significa que o máximo disponível pode mudar nas versões.

Gostaria de poder adicionar isso em um comentário - não é suficiente representante, desculpe.

Eu executei alguns testes de perf - esperando que o JSON.Stringify (LocalStorage). Comprimento seja um OP caro em uma grande ocupação de armazenamento local.

http://jsperf.com/occupied-localstorage-json-tringify-mength

É de fato tão - cerca de 50x mais caro do que acompanhar o que você está armazenando e piora o local mais cheio.

Esta função recebe o exato armazenamento disponível / à esquerda:

Fiz uma suíte de funções úteis para o LocalStorage *aqui*

http://jsfiddle.net/kzq6jgqa/3/

function getLeftStorageSize() {
    var itemBackup = localStorage.getItem("");
    var increase = true;
    var data = "1";
    var totalData = "";
    var trytotalData = "";
    while (true) {
        try {
            trytotalData = totalData + data;
            localStorage.setItem("", trytotalData);
            totalData = trytotalData;
            if (increase) data += data;
        } catch (e) {
            if (data.length < 2) break;
            increase = false;
            data = data.substr(data.length / 2);
        }
    }
    localStorage.setItem("", itemBackup);

    return totalData.length;
}

// Examples
document.write("calculating..");
var storageLeft = getLeftStorageSize();
console.log(storageLeft);
document.write(storageLeft + "");

// to get the maximum possible *clear* the storage 
localStorage.clear();
var storageMax = getLeftStorageSize();

Observe que isso não é muito rápido, então não use isso o tempo todo.

Com isso, também descobri que: o nome do item ocupará tanto espaço quanto seu comprimento, o valor do item também ocupará tanto espaço quanto seu comprimento.

Armazenamento máximo que recebi - tudo cerca de 5m:

  • 5000000 CARS - Edge
  • 5242880 Chars - Chrome
  • 5242880 Chars - Firefox
  • 5000000 chars - ou seja

Você encontrará algum código superficiado no violino para ver o progresso no console.

Levei algum tempo para fazer, espero que isso ajude ☺

Eu precisava realmente simular e testar o que meu módulo fará quando o armazenamento estiver cheio, então eu precisava obter uma precisão próxima quando o armazenamento estiver cheio, em vez da resposta aceita, o que perde essa precisão a uma taxa de i^2.

Aqui está o meu script, que sempre deve produzir uma precisão de 10 quando a tampa da memória é alcançada e rapidamente, apesar de ter algumas otimizações fáceis ... editar: melhorei o script e com uma precisão exata:

function fillStorage() {
    var originalStr = "1010101010";
    var unfold = function(str, times) {
        for(var i = 0; i < times; i++)
            str += str;
        return str;
    }
    var fold = function(str, times) {
        for(var i = 0; i < times; i++) {
            var mid = str.length/2;
            str = str.substr(0, mid);
        }
        return str;
    }

    var runningStr = originalStr;
    localStorage.setItem("filler", runningStr);
    while(true) {
        try {
            runningStr = unfold(runningStr, 1);
            console.log("unfolded str: ", runningStr.length)
            localStorage.setItem("filler", runningStr);
        } catch (err) {
            break;
        }
    }

    runningStr = fold(runningStr, 1);  
    var linearFill = function (str1) {
        localStorage.setItem("filler", localStorage.getItem("filler") + str1);
    }
    //keep linear filling until running string is no more...
    while(true) {
        try {
            linearFill(runningStr)
        } catch (err) {
            runningStr = fold(runningStr, 1);
            console.log("folded str: ", runningStr.length)
            if(runningStr.length == 0)
                break;
        }
    }

    console.log("Final length: ", JSON.stringify(localStorage).length)
}

Isso pode ajudar alguém. No Chrome, é possível pedir ao usuário que permita usar mais espaço em disco, se necessário:

// Request Quota (only for File System API)  
window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) {
  window.webkitRequestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler); 
}, function(e) {
  console.log('Error', e); 
});

Visita https://developers.google.com/chrome/whitepapers/storage#asking_more para mais informações.

 try {
     var count = 100;
     var message = "LocalStorageIsNOTFull";
     for (var i = 0; i <= count; count + 250) {
         message += message;
         localStorage.setItem("stringData", message);
         console.log(localStorage);
         console.log(count);
     }

 }
 catch (e) {
     console.log("Local Storage is full, Please empty data");
     // fires When localstorage gets full
     // you can handle error here ot emply the local storage
 }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top