¿Cuál es el tamaño máximo de los valores de localStorage?

542

Dado que localStorage(actualmente) solo admite cadenas como valores, y para hacer eso, los objetos deben ser encadenados (almacenados como cadenas JSON) antes de que puedan almacenarse, existe una limitación definida con respecto a la longitud de los valores.

¿Alguien sabe si hay una definición que se aplique a todos los navegadores?

Codekie
fuente
15
Creo que nadie respondió la pregunta "longitud máxima por valor".
Pete Alvin
@PeteAlvin Acabo de responder la pregunta .
user2428118
@PeteAlvin Alguien respondió en 2015. Las otras respuestas abordan el límite del tamaño total, pero no el límite del tamaño por valor .
Ali

Respuestas:

420

Citando del artículo de Wikipedia sobre almacenamiento web :

El almacenamiento web se puede ver de manera simple como una mejora en las cookies, proporcionando una capacidad de almacenamiento mucho mayor ( 10 MB por origen en Google Chrome ( https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh ), Mozilla Firefox y Opera; 10 MB por área de almacenamiento en Internet Explorer ) y mejores interfaces programáticas.

Y también citando un artículo de John Resig [publicado en enero de 2007]:

Espacio de almacenamiento

Está implícito que, con DOM Storage, tiene considerablemente más espacio de almacenamiento que las limitaciones típicas de agente de usuario impuestas a las Cookies. Sin embargo, la cantidad que se proporciona no está definida en la especificación, ni es transmitida de manera significativa por el agente de usuario.

Si observa el código fuente de Mozilla, podemos ver que 5120 KB es el tamaño de almacenamiento predeterminado para un dominio completo. Esto le da considerablemente más espacio para trabajar que una cookie típica de 2 KB.

Sin embargo, el tamaño de esta área de almacenamiento puede ser personalizado por el usuario (por lo que un área de almacenamiento de 5 MB no está garantizada, ni está implícita) y el agente de usuario (Opera, por ejemplo, solo puede proporcionar 3 MB, pero solo el tiempo lo dirá). )

Daniel Vassallo
fuente
28
@Cupidvogel no, significa que cada domain( origin) puede almacenar 5 MB en cualquier cliente individual. Los datos se almacenan en la máquina del cliente; de ​​ninguna manera el localStoragemecanismo interactúa entre los clientes.
DanielB
66
No, solo quería asegurarme de que se pueda acceder a los mismos datos en varias páginas para el mismo dominio. A menudo encuentro las frases dominio y página enunciadas como sinónimos, ¡así que solo quería saber con seguridad!
SexyBeast
99
¿Existe, sin embargo, una limitación en un solo valor? (Si tengo muchas banderas para almacenar, ¿qué tan seguro es almacenarlo como JSON en una sola propiedad?)
phtrivier
55
Tengo Safari a 5 MB y Chrome 39 a 10 MB (no estoy seguro de cuándo se aumentó desde 5 MB). Vea este artículo html5rocks.com/en/tutorials/offline/quota-research
Ally
18
@Cupidvogel: No, es no por dominio, que es de origen , ya que el término se utiliza vis-a-vis la política de mismo origen y dicho: Esquema + alojamiento + puerto. http://example.comy https://example.comno son del mismo origen (diferentes esquemas). http://example.comy http://www.example.comno son del mismo origen (diferentes hosts). http://example.comy http://example.com:8080no son del mismo origen (puertos diferentes). HTH. :-)
TJ Crowder
134

En realidad, Opera no tiene un límite de 5 MB. Ofrece aumentar el límite ya que las aplicaciones requieren más. El usuario puede incluso elegir "Almacenamiento ilimitado" para un dominio.

Puede probar fácilmente los límites / cuota de almacenamiento local usted mismo.

Tom Adler
fuente
50
Ya no bloquea Chrome ... Punto interesante: 5MB equivale a 2.5 millones de caracteres en Chrome. Aparentemente, UFT16 se usa para localStore.
Felix Alcala
1
@FelixAlcala Desafortunadamente, bloquea Chrome 15.0.874.54 beta en Mac OS X. Tuve un bloqueo de 1.500.000 caracteres.
Ivan Vučica
Se bloqueó Chrome en mi dispositivo, también restableció el bckground, sin embargo, no me sorprende, mi teléfono tiene tan poca RAM, no puede soportar tener una estúpida APLICACIÓN DE LINTERNA abierta mientras Chrome está abierto.
Jack
66
@FelixAlcala - En realidad, JavaScript expone UCS-2. Si bien es similar, UFT16hay algunas diferencias muy importantes ... sobre todo en torno al hecho de que UCS-2 es anterior a UFT.
Jeremy J Starcher
@FelixAlcala ¿Cree que es una buena idea mostrar cuántos caracteres, así como su tamaño de disco equivalente (por ejemplo, 2,700K caracteres ~ = 5,274 KB)?
AJ Hsu
76

Aquí hay un guión sencillo para descubrir el límite:

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

Aquí está la esencia , JSFiddle y la publicación del blog .

El script probará la configuración de cadenas de texto cada vez más grandes hasta que el navegador arroje una excepción. En ese punto, borrará los datos de prueba y establecerá una clave de tamaño en localStorage almacenando el tamaño en kilobytes.

cdmckay
fuente
1
Solución genial Encontré este trazador de líneas , ¿qué te parece?
brasofilo
2
@brasofilo Creo que un revestimiento supone que tiene 5 MB y luego resta la cantidad que se está utilizando.
cdmckay
Ooook, tiro seguro. El problema que tengo con su código es no poder obtener resultados correctos con la forma correcta de convertir el tamaño en bytes a KB, MB, GB en Javascript ... Lo revisaré mañana, pero si pueden echarle un vistazo, apreciado.
brasofilo
1
mejoró el rendimiento y la calidad de esta respuesta aquí
smnbbrv
Es 2020 y esta respuesta funciona perfectamente bien en Vanilla Chrome y Firefox en Win10, dando un tamaño = 5000.
A. Chiesa
34

Encuentre la longitud máxima de una sola cadena que se puede almacenar en localStorage

Este fragmento encontrará la longitud máxima de una cadena que se puede almacenar localStoragepor 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>

Tenga en cuenta que la longitud de una cadena está limitada en JavaScript; si desea ver la cantidad máxima de datos que se pueden almacenar localStoragecuando no se limita a una sola cadena, puede usar el código en esta respuesta .

Editar: los fragmentos de pila no son compatibles localStorage, por lo que aquí hay un enlace a 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

Obtengo resultados diferentes en cada ejecución en Internet Explorer.

usuario2428118
fuente
1
Es gracioso, pero su simple prueba detiene mi sistema bastante poderoso cuando lo pruebo en el navegador Edge (en Win 10) después de aproximadamente 1 minuto de ejecución. Así que no puedo agregar nuevos datos a sus resultados))
vatavale
33

Navegadores móviles:

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

Navegadores de escritorio:

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

Link de referencia

Behnam Mohammadi
fuente
66
¿De dónde vienen los números?
MrD
23
@BehnamMohammadi, ¿puedes agregar una referencia de dónde lo sacaste para completarlo
Chris Lang
1
Y nunca se rellenó ninguna referencia. Pero para la posteridad, estos números cambian un poco. Deberíamos actualizar esto con más navegadores y la información actual.
Malavos
3
@ChrisLang agregó enlace
Behnam Mohammadi
1
@Malavos agregó enlace
Behnam Mohammadi
13

No desea encadenar objetos grandes en una sola entrada localStorage. Eso sería muy ineficiente: todo se tendría que analizar y volver a codificar cada vez que cambien algunos pequeños detalles. Además, JSON no puede manejar múltiples referencias cruzadas dentro de una estructura de objeto y borra muchos detalles, por ejemplo, el constructor, las propiedades no numéricas de las matrices, lo que hay en una entrada dispersa, etc.

En cambio, puedes usar Rhaboo . Almacena objetos grandes usando muchas entradas de localStorage para que pueda hacer pequeños cambios rápidamente. Los objetos restaurados son copias mucho más precisas de los guardados y la API es increíblemente simple. P.ej:

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

Por cierto, lo escribí.

Adrian May
fuente
1
Gracias martin También podrías consultar mi repositorio 'evon'. En este momento, solo es un serializador y la tinta está muy húmeda, pero es más rápida que el rhaboo e igualmente versátil. Rhaboo pronto se convertirá para usarlo internamente.
Adrian May
77
Útil, pero no creo que esto aborde la pregunta "¿Cuál es el tamaño máximo de localStorage;" su respuesta podría mejorarse al indicar qué sucede cuando esta biblioteca intenta almacenar algo más allá del límite de tamaño y cómo reaccionar ante él.
Chris Moschini
6

Estoy haciendo lo siguiente:

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
fuente
55
Maroun Maroun: Verifique la publicación nuevamente, el autor ha proporcionado un código para verificar mediante programación el tamaño máximo del almacenamiento local. Esto parece ser una respuesta válida, y no otra pregunta.
Arend
La ejecución de estos códigos arroja un error de "Declaración de devolución ilegal" en Chrome, en el momento de la escritura
DrewT
6

Realmente me gusta la respuesta de cdmckay , pero realmente no se ve bien verificar el tamaño en tiempo real: es demasiado lento (2 segundos para mí). Esta es la versión mejorada, que es mucho más rápida y más exacta, también con una opción para elegir qué tan grande puede ser el error (por defecto 250,000, el error más pequeño es - cuanto más largo es el 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;
  }
}

Probar:

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

Esto funciona dramáticamente más rápido para el error estándar; También puede ser mucho más exacto cuando sea necesario.

smnbbrv
fuente
6

He condensado una prueba binaria en esta función que 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)
}

También realiza una copia de seguridad del contenido antes de la prueba, luego los restaura.

Cómo funciona: duplica el tamaño hasta que se alcanza el límite o la prueba falla. Luego almacena la mitad de la distancia entre bajo y alto y resta / agrega la mitad de la mitad cada vez (resta en caso de falla y agrega en caso de éxito); perfeccionando el valor adecuado.

upperLimites 1GB por defecto, y solo limita qué tan alto hacia arriba escanear exponencialmente antes de comenzar la búsqueda binaria. Dudo que esto deba cambiarse, pero siempre estoy pensando en el futuro. ;)

En 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 y FireFox también informan el mismo tamaño máximo (10485762 bytes).

James Wilkins
fuente
1
(Y no se olvide de localStorage.Clear()antes y después de su prueba
simonmysun
5

Puede usar el siguiente código en los navegadores modernos para verificar de manera eficiente la cuota de almacenamiento (total y usado) en tiempo 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
fuente
No funciona bien para Chrome. Usage (in Bytes): 647 , Total Quota (in Bytes): 32901464711 Eso está mal: el tamaño total posible es en realidad 10485762.
James Wilkins
1

Una vez que desarrollé la extensión de Chrome (navegador de escritorio) y probé el almacenamiento local tamaño máximo real de por este motivo.

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

Más que el 10240 KBuso me devolvió el error:

Excepción DOM no capturada: no se pudo ejecutar 'setItem' en 'Almacenamiento': la configuración del valor de 'notas' excedió la cuota.

colina de humo
fuente
0

Escribí este código simple que está probando el tamaño localStorage en 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 de Github:

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

Tengo los mismos resultados en Chrome de escritorio, Opera, Firefox, Chrome Brave y Mobile que es ~ 5Mbytes

ingrese la descripción de la imagen aquí

Y un resultado medio pequeño en safari ~ 2Mbytes

ingrese la descripción de la imagen aquí

gkucmierz
fuente