Obliczanie wykorzystania przestrzeni localStorage

Tworzę aplikację przy użyciu edytora Bespin i localStorage HTML5. Przechowuje wszystkie pliki lokalnie i pomaga w gramatyce, używa JSLint i niektórych innych parserów dla CSS i HTML, aby pomóc użytkownikowi.

Chcę obliczyć, ile z limitu localStorage został wykorzystany i ile faktycznie tam jest. Czy jest to możliwe dzisiaj? myślałem, aby nie po prostu obliczyć bity, które są przechowywane. Ale z drugiej strony nie jestem pewien, co jeszcze jest, czego nie mogę sobie zmierzyć.

Author: JeroenEijkhof, 2010-06-12

12 answers

Możesz uzyskać przybliżony pomysł za pomocą metod JSON, aby zamienić cały obiekt localStorage na łańcuch JSON:

JSON.stringify(localStorage).length

Nie wiem, jak by to było dokładne, zwłaszcza z kilkoma bajtami dodanych znaczników, jeśli używasz dodatkowych obiektów - ale myślę, że to lepsze niż myślenie, że wciskasz tylko 28K, a zamiast tego robisz 280K (lub odwrotnie).

 67
Author: Morgon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-07 19:05:21

Nie znalazłem uniwersalnego sposobu, aby uzyskać pozostały limit w przeglądarkach, których potrzebowałem, ale dowiedziałem się, że kiedy osiągniesz limit, pojawia się komunikat o błędzie. Jest to oczywiście inne w każdej przeglądarce.

Aby go maksymalnie wykorzystać użyłem tego małego skryptu:

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

Z tego mam taką informację:

Google Chrome

  • DOMException:
    • kod: 22
    • message: "Failed to execute 'setItem' on 'Storage': Setting the wartość "danych" przekroczyła kwotę."
    • Nazwa: "QuotaExceededError"

Mozilla Firefox

  • DOMException:
    • Kod: 1014
    • wiadomość: "osiągnięto maksymalny rozmiar pamięci trwałej"
    • Nazwa: "NS_ERROR_DOM_QUOTA_REACHED"

Safari

  • DOMException:
    • kod: 22
    • message: "QuotaExceededError: Dom Exception 22"
    • Nazwa: "QuotaExceededError"

Internet Explorer, Edge (community)

  • DOMException:
    • kod: 22
    • wiadomość: "QuotaExceededError"
    • Nazwa: "QuotaExceededError"

Moje rozwiązanie

Jak na razie moim rozwiązaniem jest dodanie dodatkowego połączenia za każdym razem, gdy użytkownik coś zapisze. A jeśli wyjątek zostanie złapany, powiedziałbym im, że kończy im się pamięć pojemność.


Edit: Delete the added data

Zapomniałem wspomnieć, że aby to naprawdę zadziałało, musisz usunąć DATA element, który został pierwotnie ustawiony. Zmiana jest odzwierciedlona powyżej za pomocą funkcji removeItem().

 47
Author: JeroenEijkhof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-03 11:56:37

IE8 implementuje remainingSpace właściwość do tego celu:

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

Niestety wydaje się, że nie jest to dostępne w innych przeglądarkach. Nie jestem jednak pewien, czy realizują one coś podobnego.

 27
Author: Daniel Vassallo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-12 01:52:19

Możesz użyć poniższego wiersza, aby dokładnie obliczyć tę wartość, a Oto jsfiddle dla zilustrowania jego użycia

alert(1024 * 1024 * 5 - escape(encodeURIComponent(JSON.stringify(localStorage))).length);
 12
Author: jas-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-10 02:17:48

Natknąłem się na to dzisiaj podczas testów (przekroczenie limitu pamięci) i stworzyłem rozwiązanie. IMO, wiedza o tym, jaki jest limit i gdzie jesteśmy w związku, jest znacznie mniej cenna niż wdrożenie funkcjonalnego sposobu dalszego przechowywania poza limitem.

Dlatego zamiast próbować porównywać rozmiar i sprawdzać pojemność, możemy reagować, gdy osiągniemy limit, zmniejszyć naszą bieżącą pamięć o jedną trzecią i wznowić przechowywanie. Jeśli wspomniana redukcja nie powiedzie się, przestań przechowywać.

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

Ta funkcja mieszka w obiekcie owijarki, tak publicznym.set po prostu wywołuje sam siebie. Teraz możemy dodać do magazynu i nie martwić się, jaki jest kontyngent lub jak blisko jesteśmy zbyt go. Jeśli pojedynczy sklep przekracza 1 / 3rd rozmiar kontyngentu jest gdzie ta funkcja przestanie culling i zamknąć przechowywanie, i w tym momencie, nie powinno być buforowania, prawda?

 8
Author: Shiboe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-26 21:41:07

Aby dodać do wyników testów przeglądarki:

Firefox i=22.

Safari Wersja 5.0.4 na moim Macu nie zawiesiła się. Błąd jako Chrome. i=21.

Opera Informuje użytkownika, że strona internetowa chce przechowywać dane, ale nie ma wystarczającej ilości miejsca. Użytkownik może odrzucić żądanie, zwiększyć limit do wymaganej kwoty lub do kilku innych limitów, lub ustawić go na nieograniczony. Przejdź do opery: webstorage, aby powiedzieć, czy ta wiadomość się pojawia, czy nie. i=20. Błąd wyrzucony jest taki sam jak Chrome.

Tryb standardów IE9 Błąd jako Chrome. i=22.

IE9 w trybie standardów IE8 Komunikat konsoli "Error: Not enough storage is available to complete this operation". i=22

IE9 w starszych trybach błąd obiektu. i=22.

IE8 Nie mam kopii do przetestowania, ale pamięć lokalna jest obsługiwana (http://stackoverflow.com/questions/3452816/does-ie8-support-out-of-the-box-in-localstorage)

IE7 i poniżej Nie obsługuje magazyn lokalny.

 5
Author: user535673,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-06 09:18:55

Możesz przetestować swoją przeglądarkę za pomocą tego web storage support test

Testowałem Firefox zarówno na moim tablecie z Androidem, jak i laptopie z systemem windows i Chromium tylko na windows wyniki:

  1. Firefox(windows):

    • localStorage : 5120k char
    • sessionStorage : 5120k char
    • localStorage: *nie obsługiwane
  2. Firefox(android): {]}

    • localStorage : 2560k char
    • W przeciwieństwie do poprzednich wersji, nie jest to możliwe.]}
    • localStorage: nie obsługiwane
  3. Chrom(windows):

    • localStorage : 5120k char
    • sessionStorage: 5120k char
    • localStorage: nie obsługiwane

Update

Na Google Chrome w wersji 52.0.2743.116 M (64-bitowe) limity, gdzie trochę niżej na znakach 5101k. Oznacza to, że maksymalna Dostępna ilość może ulec zmianie w wersjach.

 3
Author: Morteza Tourani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-24 05:31:06

Chciałbym to dodać w komentarzu - za mało rep, sorry.

Przeprowadziłem kilka testów perf-oczekując JSONA.stringify (localStorage).długość, aby być kosztownym op przy dużych lokalnymstorage obłożenie.

Http://jsperf.com/occupied-localstorage-json-stringify-length

Rzeczywiście tak jest-około 50x droższe niż śledzenie tego, co przechowujesz, i pogarsza się im pełniejsze localStorage dostaje.

 2
Author: SashaK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-16 13:52:39

Ta funkcja otrzymuje dokładny magazyn dostępny / od lewej:

Zrobiłem zestaw przydatnych funkcji dla localStorage *tutaj *

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

zauważ, że nie jest to bardzo szybkie, więc nie używaj go cały czas.

Z tym odkryłem również, że: nazwa elementu zajmie tyle miejsca, ile jego długość, wartość elementu zajmie również tyle miejsca, ile ich długość.

Maximum storage I got - wszystko o 5M:

  • 5000000 znaków - krawędź
  • 5242880 chars-Chrom
  • 5242880 znaków-Firefox
  • 5000000 znaków-IE

znajdziesz w nim trochę komentowanego kodu, aby zobaczyć postępy w konsoli.

Zajęło mi trochę czasu, mam nadzieję, że to pomoże ☺

 1
Author: CoderPi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:06

Musiałem właściwie symulować i przetestować, co mój moduł zrobi, gdy magazyn jest pełny, więc musiałem uzyskać dokładność, gdy magazyn jest pełny, a nie akceptowaną odpowiedź, która traci tę precyzję z szybkością i^2.

Oto mój skrypt, który powinien zawsze produkować precyzję 10 na po osiągnięciu limitu pamięci, i dość szybko, pomimo kilku łatwych optymalizacji... EDIT: poprawiłem skrypt i z dokładną precyzją:

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)
}
 1
Author: balthatrix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-27 20:19:04

To może komuś pomóc. W chrome można poprosić Użytkownika o pozwolenie na użycie większej ilości miejsca na dysku w razie potrzeby:

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

Wizyta https://developers.google.com/chrome/whitepapers/storage#asking_more aby uzyskać więcej informacji.

 0
Author: Remo H. Jansen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-23 16:14:44
 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
 }
 0
Author: jinal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-24 13:39:44