wake-up-neo.com

Was ist die maximale Größe von localStorage-Werten?

Da localStorage (derzeit) nur Strings als Werte unterstützt und dazu die Objekte stringifiziert (als JSON-String gespeichert) werden müssen, bevor sie gespeichert werden können, gibt es eine definierte Einschränkung hinsichtlich der Länge des Werte.

Weiß jemand, ob es eine Definition gibt, die für alle Browser gilt?

480
Codekie

Zitat aus dem Wikipedia-Artikel über Web Storage :

Der Web-Speicher kann vereinfacht als Verbesserung von Cookies angesehen werden und bietet eine viel größere Speicherkapazität ( 10 MB pro Origin in Google Chrome ( https://plus.google.com/u)/0/+ FrancoisBeaufort/posts/S5Q9HqDB8bh ), Mozilla Firefox und Opera: 10 MB pro Speicherbereich im Internet Explorer ) und bessere Programmierschnittstellen.

Und auch aus einem Artikel von John Resig [vom Januar 2007] zitiert:

Speicherplatz

Es wird vorausgesetzt, dass Sie mit DOM-Speicher erheblich mehr Speicherplatz haben als die typischen Einschränkungen von Benutzeragenten, die Cookies auferlegen. Der bereitgestellte Betrag ist jedoch weder in der Spezifikation definiert, noch wird er vom Benutzeragenten sinnvoll übertragen.

Wenn Sie sich den Mozilla-Quellcode ansehen, sehen Sie, dass 5120 KB die Standardspeichergröße für eine gesamte Domain ist. Dadurch haben Sie erheblich mehr Platz zum Arbeiten als bei einem typischen 2-KB-Cookie.

Die Größe dieses Speicherbereichs kann jedoch vom Benutzer (so dass ein Speicherbereich von 5 MB nicht garantiert oder impliziert wird) und vom Benutzer angepasst werden agent (Opera zum Beispiel liefert möglicherweise nur 3 MB - aber nur die Zeit wird es zeigen.)

391
Daniel Vassallo

Tatsächlich hat Opera kein Limit von 5 MB. Es bietet sich an, die Grenze zu erhöhen, da Anwendungen mehr erfordern. Der Benutzer kann sogar "Unbegrenzten Speicherplatz" für eine Domain auswählen.

Sie können ganz einfach localStorage limits/quota testen sich.

122

Hier ist ein einfaches Skript, um das Limit herauszufinden:

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

Hier ist the Gist , JSFiddle und Blogpost .

Das Skript testet das Festlegen immer größerer Textzeichenfolgen, bis der Browser eine Ausnahme auslöst. An diesem Punkt werden die Testdaten gelöscht und in localStorage ein Größenschlüssel festgelegt, der die Größe in Kilobyte speichert.

67
cdmckay

Mobile Browser:

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

Desktop-Browser:

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

Referenzlink

29

Finde die maximale Länge einer einzelnen Zeichenkette, die in localStorage gespeichert werden kann

Dieses Snippet ermittelt die maximale Länge eines Strings, der in localStorage pro Domain gespeichert werden kann.

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

Beachten Sie, dass die Länge einer Zeichenfolge in JavaScript begrenzt ist. Wenn Sie die maximale Datenmenge anzeigen möchten, die in localStorage gespeichert werden kann, ohne auf eine einzelne Zeichenfolge beschränkt zu sein, können Sie den Code in dieser Antwort verwenden .

Bearbeiten: Stack-Snippets unterstützen localStorage nicht, also hier ist ein Link zu JSFiddle .

Ergebnisse

Chrome (45.0.2454.101): 5242878 Zeichen
Firefox (40.0.1): 5242883 Zeichen
Internet Explorer (11.0.9600.18036) 16386122066 122070 Zeichen

Ich erhalte bei jedem Lauf im Internet Explorer unterschiedliche Ergebnisse.

27
user2428118

Gehen Sie nicht davon aus, dass 5 MB verfügbar sind - die Kapazität von localStorage variiert je nach Browser. Die häufigsten Werte sind 2,5 MB, 5 MB und unbegrenzt. Quelle: http://dev-test.nemikor.com/web-storage/support-test/

24
tagawa

Sie möchten keine großen Objekte zu einem einzigen localStorage-Eintrag zusammenfassen. Das wäre sehr ineffizient - das Ganze müsste bei jeder geringfügigen Detailänderung analysiert und neu codiert werden. Außerdem kann JSON nicht mit mehreren Querverweisen innerhalb einer Objektstruktur umgehen und löscht viele Details, z. der Konstruktor, nicht numerische Eigenschaften von Arrays, was sich in einem spärlichen Eintrag befindet usw.

Stattdessen können Sie Rhaboo verwenden. Es speichert große Objekte mit vielen localStorage-Einträgen, sodass Sie kleine Änderungen schnell vornehmen können. Die wiederhergestellten Objekte sind viel genauere Kopien der gespeicherten und die API ist unglaublich einfach. Z.B.:

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

Übrigens habe ich es geschrieben.

13
Adrian May

Ich mag cdmckays Antwort , aber es sieht nicht gut aus, die Größe in Echtzeit zu überprüfen: Es ist einfach zu langsam (2 Sekunden für mich). Dies ist die verbesserte Version, die viel schneller und genauer ist. Sie kann auch ausgewählt werden, wie groß der Fehler sein soll (Standardwert 250,000, je kleiner der Fehler ist - je länger die Berechnung ist):

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

Zu testen:

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

Dies funktioniert für den Standardfehler erheblich schneller. es kann auch viel genauer sein, wenn nötig.

6
smnbbrv

Mit dem folgenden Code können Sie in modernen Browsern das Speicherkontingent (gesamt und belegt) effizient in Echtzeit überprüfen:

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

Ich mache folgendes:

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

Ich habe einen Binärtest in dieser Funktion zusammengefasst, die ich verwende:

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

Außerdem werden die Inhalte vor dem Testen gesichert und anschließend wiederhergestellt.

So funktioniert es: Es verdoppelt die Größe, bis das Limit erreicht ist oder der Test fehlschlägt. Es speichert dann die Hälfte des Abstands zwischen niedrig und hoch und subtrahiert/addiert jedes Mal die Hälfte (subtrahiert bei Misserfolg und addiert bei Erfolg); Honen auf den richtigen Wert.

upperLimit ist standardmäßig 1 GB groß und begrenzt nur, wie weit nach oben exponentiell gescannt werden soll, bevor die binäre Suche gestartet wird. Ich bezweifle, dass dies geändert werden muss, aber ich denke immer voraus. ;)

Auf 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 und FireFox melden ebenfalls dieselbe maximale Größe (10485762 Byte).

4
James Wilkins

Einmal habe ich die Chrome (Desktop Browser) Erweiterung entwickelt und Local Storage aus diesem Grund die maximale Größe getestet.

Meine Ergebnisse:

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

Mehr als die Verwendung von 10240 KB hat mir den Fehler zurückgegeben:

Nicht abgefangene DOMException: Fehler beim Ausführen von 'setItem' für 'Storage': Das Festlegen des Werts für 'notes' hat das Kontingent überschritten.

1
smokehill