QuotaExceededError: Dom excepción 22: Se intentó agregar algo al almacenamiento que excedía la cuota


Usando localStorage en iPhone con iOS 7 lanza este error. He estado buscando un resolant, pero teniendo en cuenta que ni siquiera estoy navegando en privado, nada es relevante.

No entiendo por qué localStorage se deshabilitaría de forma predeterminada en iOS 7, pero parece que lo es? He probado en otros sitios web, así, pero sin suerte. Incluso intenté probarlo usando este sitio web: http://arty.name/localstorage.html, pero no parece que esté guardando nada en absoluto para algunos una razón extraña.

¿Alguien ha tenido el mismo problema, solo que ha tenido suerte arreglándolo? ¿Debo cambiar mi método de almacenamiento?

Intenté depurarlo almacenando solo unas pocas líneas de información, pero fue en vano. Usé la función estándar localStorage.setItem() para guardar.

Author: NicT, 2014-01-16

9 answers

Esto puede ocurrir cuando Safari está en modo privado de navegación. Durante la navegación privada, el almacenamiento local no está disponible en absoluto.

Una solución es advertir al usuario que la aplicación necesita el modo no privado para funcionar.

ACTUALIZACIÓN: Esto se ha solucionado en Safari 11, por lo que el comportamiento ahora está alineado con otros navegadores.

 347
Author: Cristian Dinu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-20 12:39:54

Como se mencionó en otras respuestas, siempre obtendrá el error QuotaExceededError en el modo Safari Private Browser tanto en iOS como en OS X cuando se llame a localStorage.setItem (o sessionStorage.setItem).

Una solución es hacer un try/catch o Modernizr check en cada instancia de uso de setItem.

Sin embargo, si desea una cuña que simplemente detenga globalmente este error, para evitar que el resto de su JavaScript se rompa, puede usar esto:

Https://gist.github.com/philfreo/68ea3cd980d72383c951

// Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem
// throw QuotaExceededError. We're going to detect this and just silently drop any calls to setItem
// to avoid the entire page breaking, without having to do a check at each usage of Storage.
if (typeof localStorage === 'object') {
    try {
        localStorage.setItem('localStorage', 1);
        localStorage.removeItem('localStorage');
    } catch (e) {
        Storage.prototype._setItem = Storage.prototype.setItem;
        Storage.prototype.setItem = function() {};
        alert('Your web browser does not support storing settings locally. In Safari, the most common cause of this is using "Private Browsing Mode". Some settings may not save or some features may not work properly for you.');
    }
}
 102
Author: philfreo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-22 19:16:05

Utilizo esta función simple, que devuelve true o false, para probar la disponibilidad de localStorage:

isLocalStorageNameSupported = function() {
    var testKey = 'test', storage = window.sessionStorage;
    try {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return true;
    } catch (error) {
        return false;
    }
}

Ahora puede probar la disponibilidad de localStorage.setItem() antes de usarla. Ejemplo:

if ( isLocalStorageNameSupported() ) {
    // can use localStorage.setItem('item','value')
} else {
    // can't use localStorage.setItem('item','value')
}
 16
Author: DrewT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-11 18:07:24

Me pasó a ejecutar con el mismo problema en iOS 7 (con algunos dispositivos no simuladores).

Parece que Safari en iOS 7 tiene una cuota de almacenamiento más baja, que aparentemente se alcanza al tener un largo historial de registro.

Supongo que la mejor práctica será atrapar la excepción.

El proyecto Modernizr tiene un parche fácil, deberías probar algo similar: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js

 5
Author: rodowi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-13 00:30:00

Aquí hay una solución ampliada basada en la respuesta de DrewT anterior que utiliza cookies si localStorage no está disponible. Utiliza la biblioteca docCookies de Mozilla :

function localStorageGet( pKey ) {
    if( localStorageSupported() ) {
        return localStorage[pKey];
    } else {
        return docCookies.getItem( 'localstorage.'+pKey );
    }
}

function localStorageSet( pKey, pValue ) {
    if( localStorageSupported() ) {
        localStorage[pKey] = pValue;
    } else {
        docCookies.setItem( 'localstorage.'+pKey, pValue );
    }
}

// global to cache value
var gStorageSupported = undefined;
function localStorageSupported() {
    var testKey = 'test', storage = window.sessionStorage;
    if( gStorageSupported === undefined ) {
        try {
            storage.setItem(testKey, '1');
            storage.removeItem(testKey);
            gStorageSupported = true;
        } catch (error) {
            gStorageSupported = false;
        }
    }
    return gStorageSupported;
}

En tu fuente, solo usa:

localStorageSet( 'foobar', 'yes' );
...
var foo = localStorageGet( 'foobar' );
...
 3
Author: Stickley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-08 17:11:54

Como ya se explicó en otras respuestas, cuando está en modo de navegación privada Safari siempre lanzará esta excepción cuando intente guardar datos con localStorage.setItem() .

Para arreglar esto escribí un localStorage falso que imita localStorage, tanto métodos como eventos.

Falso localStorage: https://gist.github.com/engelfrost/fd707819658f72b42f55

Esta no es probablemente una buena solución general al problema. Esta fue una buena solución para mi escenario, donde la alternativa sería mayor reescribe a una aplicación ya existente.

 2
Author: Josef Engelfrost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-01 11:21:30

Actualización (2016-11-01)

Estaba usando AmplifyJS mencionados a continuación para solucionar este problema. Sin embargo, para Safari en la navegación privada, estaba volviendo a un almacenamiento basado en memoria. En mi caso, no era apropiado porque significa que el almacenamiento se borra en la actualización, incluso si el usuario todavía está en navegación privada.

También, he notado un número de usuarios que siempre están navegando en modo privado en iOS Safari. Por esa razón, una mejor alternativa para Safari es usar cookies (si disponible). De forma predeterminada, las cookies siguen siendo accesibles incluso en la navegación privada. Por supuesto, se borran al salir de la navegación privada, pero no se borran al actualizar.

Encontré la biblioteca local-storage-fallback. De la documentación:

Propósito

Con la configuración del navegador como "Navegación privada" se ha convertido en un problema para confiar en una ventana de trabajo.localStorage, incluso en navegadores más nuevos. Aunque pueda existir, lanzará excepciones al intentar usar setItem o getItem. Este módulo ejecutará las comprobaciones apropiadas para ver qué mecanismo de almacenamiento del navegador podría estar disponible, y luego lo expondrá. Utiliza la misma API que localStorage, por lo que debería funcionar como un reemplazo directo en la mayoría de los casos.

Cuidado con las trampas:

  • CookieStorage tiene límites de almacenamiento. Ten cuidado aquí.
  • MemoryStorage no persistirá entre cargas de página. Esto es más o menos un stop-gap para evitar la página se bloquea, pero puede ser suficiente para los sitios web que no hacen cargas de página completa.

TL; DR: {[14]]}

Use local-storage-fallback (API unificada con .getItem(prop) y .setItem(prop, val)):

Compruebe y utilice el adaptador de almacenamiento apropiado para el navegador (localStorage, sessionStorage, cookies, memoria)

Respuesta original

Para agregar respuestas anteriores, una posible solución sería cambiar el método de almacenamiento. Hay algunas librairies tales como AmplifyJSy PersistJS que pueden ayudar. Ambas bibliotecas permiten el almacenamiento persistente del lado del cliente a través de varios backends.

Para AmplifyJS

Almacenamiento local

  • IE 8 +
  • Firefox 3.5+
  • Safari 4 +
  • Chrome
  • Opera 10.5 +
  • iPhone 2+
  • Android 2+

SessionStorage

  • IE 8 +
  • Firefox 2+
  • Safari 4 +
  • Chrome
  • Opera 10.5 +
  • iPhone 2+
  • Android 2+

GlobalStorage

  • Firefox 2+

Datos de usuario

  • IE 5-7
  • userData también existe en versiones más recientes de IE, pero debido a peculiaridades en la implementación de IE 9, no registramos userData si localStorage es compatible.

Memoria

  • Se proporciona un almacén en memoria como reserva si ninguno de los otros los tipos de almacenamiento están disponibles.

Para PersistentJS

  • flash: almacenamiento persistente Flash 8.
  • gears: Almacenamiento persistente basado en Google Gears.
  • localstorage: almacenamiento de borradores HTML5.
  • globalstorage: almacenamiento de borrador HTML5 (especificación antigua).
  • ie: comportamientos de datos de usuario de Internet Explorer.
  • cookie: Almacenamiento persistente basado en cookies.

Ofrecen una capa de abstracción para que no tengas que preocúpate por elegir el tipo de almacenamiento. Sin embargo, tenga en cuenta que puede haber algunas limitaciones (como límites de tamaño) dependiendo del tipo de almacenamiento. En este momento, estoy usando AmplifyJS, pero todavía tengo que hacer algunas pruebas más en iOS 7/Safari/etc. para ver si realmente resuelve el problema.

 2
Author: Jonathan Alzetta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-05 08:51:10

En abril de 2017 se fusionó un parche con Safari, por lo que se alineó con los otros navegadores. Esto fue lanzado con Safari 11.

Https://bugs.webkit.org/show_bug.cgi?id=157010

 1
Author: sandstrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-20 12:37:51

Esta pregunta y respuesta me ayudó a resolver un problema específico al registrar nuevos usuarios en Parse.

Debido a que la función de registro( attrs, options ) utiliza almacenamiento local para persistir en la sesión, si un usuario está en modo de navegación privada, lanza la excepción "QuotaExceededError: DOM 22: Se intentó agregar algo al almacenamiento que excediera la cuota."exception y las funciones success/error nunca se llaman.

En mi caso, porque la función de error nunca se llama inicialmente parecía ser un problema con el disparo del evento de clic en el envío o la redirección definida en el éxito de registro.

La inclusión de una advertencia para los usuarios resolvió el problema.

Parse Javascript SDK Reference https://parse.com/docs/js/api/classes/Parse.User.html#methods_signUp

Registra un nuevo usuario con un nombre de usuario (o correo electrónico) y una contraseña. Esto creará un nuevo Análisis.Usuario en el servidor, y también persisten la sesión en localStorage para que pueda acceder al usuario usando {@link #current}.

 0
Author: clayostrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-18 06:58:59