błąd HTML5 localStorage w przeglądarce Safari: "QUOTA EXCEEDED ERR: DOM wyjątek 22: podjęto próbę dodania do magazynu czegoś, co przekroczyło limit."

Moja webapp mają błędy javascript w iOS safari przeglądanie prywatne:

JavaScript: błąd

Undefined

Quota_exceeded_err: DOM wyjątek 22: podjęto próbę dodania czegoś do magazynu...

Mój kod:

localStorage.setItem('test',1)
Author: Rubens Mariuzzo, 2013-01-28

12 answers

Najwyraźniej jest to projekt. Gdy Safari (OS X lub iOS) jest w trybie przeglądania prywatnego, wygląda na to, że localStorage jest dostępna, ale próba wywołania setItem rzuca wyjątek.

store.js line 73
"QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."

Dzieje się tak, że obiekt window nadal wyświetla localStorage w globalnej przestrzeni nazw, ale gdy wywołujesz setItem, ten wyjątek jest wyrzucany. Wszelkie wywołania removeItem są ignorowane.

Wydaje mi się, że najprostszą poprawką (choć nie testowałem jeszcze tej przeglądarki krzyżowej) będzie zmiana funkcji isLocalStorageNameSupported() do testowania że można również ustawić jakąś wartość.

Https://github.com/marcuswestin/store.js/issues/42

function isLocalStorageNameSupported() 
{
    var testKey = 'test', storage = window.sessionStorage;
    try 
    {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return localStorageName in win && win[localStorageName];
    } 
    catch (error) 
    {
        return false;
    }
}
 180
Author: KingKongFrog,
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-05-26 10:44:40

Poprawka zamieszczona na powyższym linku nie działa dla mnie. This did:

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

Pochodzi z http://m.cg/post/13095478393/detect-private-browsing-mode-in-mobile-safari-on-ios5

 36
Author: cyberwombat,
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-10-20 18:30:41

Jak wspomniano w innych odpowiedziach, zawsze otrzymasz QuotaExceededError w trybie przeglądarki prywatnej Safari zarówno na iOS, jak i OS X po wywołaniu localStorage.setItem (lub sessionStorage.setItem).

Jednym z rozwiązań jest wykonanie try / catch lub Modernizr check w każdym przypadku użycia setItem.

Jeśli jednak chcesz podkładkę, która po prostu globalnie zatrzymuje ten błąd, aby zapobiec łamaniu reszty JavaScript, możesz użyć to:

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.');
    }
}
 24
Author: philfreo,
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-11-22 19:17:30

W moim kontekście, właśnie rozwinąłem abstrakcję klasową. Gdy moja aplikacja jest uruchomiona, sprawdzam, czy localStorage działa przez wywołanie getStorage () . Funkcja zwraca również:

  • albo localStorage, jeśli localStorage działa
  • lub Implementacja klasy niestandardowej LocalStorageAlternative

W moim kodzie nigdy nie wywołuję bezpośrednio localStorage. Wywołuję cusstoglobal var, zainicjowałem wywołując getStorage () .

W ten sposób działa z przeglądaniem prywatnym lub konkretnymi wersjami Safari

function getStorage() {

    var storageImpl;

     try { 
        localStorage.setItem("storage", ""); 
        localStorage.removeItem("storage");
        storageImpl = localStorage;
     }
     catch (err) { 
         storageImpl = new LocalStorageAlternative();
     }

    return storageImpl;

}

function LocalStorageAlternative() {

    var structureLocalStorage = {};

    this.setItem = function (key, value) {
        structureLocalStorage[key] = value;
    }

    this.getItem = function (key) {
        if(typeof structureLocalStorage[key] != 'undefined' ) {
            return structureLocalStorage[key];
        }
        else {
            return null;
        }
    }

    this.removeItem = function (key) {
        structureLocalStorage[key] = undefined;
    }
}

cusSto = getStorage();
 11
Author: Pierre Le Roux,
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-08 13:56:01

Aby rozszerzyć odpowiedzi innych, oto kompaktowe rozwiązanie, które nie ujawnia/nie dodaje żadnych nowych zmiennych. Nie obejmuje wszystkich baz, ale powinien pasować do większości osób, które chcą, aby aplikacja na jednej stronie pozostała funkcjonalna (pomimo braku trwałości danych po przeładowaniu).

(function(){
    try {
        localStorage.setItem('_storage_test', 'test');
        localStorage.removeItem('_storage_test');
    } catch (exc){
        var tmp_storage = {};
        var p = '__unique__';  // Prefix all keys to avoid matching built-ins
        Storage.prototype.setItem = function(k, v){
            tmp_storage[p + k] = v;
        };
        Storage.prototype.getItem = function(k){
            return tmp_storage[p + k] === undefined ? null : tmp_storage[p + k];
        };
        Storage.prototype.removeItem = function(k){
            delete tmp_storage[p + k];
        };
        Storage.prototype.clear = function(){
            tmp_storage = {};
        };
    }
})();
 4
Author: Jon,
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-02-25 09:59:42

Miałem ten sam problem przy użyciu Ionic framework (Angular + Cordova). Wiem, że to nie rozwiązuje problemu, ale jest to kod dla aplikacji Angular na podstawie powyższych odpowiedzi. Będziesz miał efemeryczne rozwiązanie dla localStorage w wersji Safari na iOS.

Oto kod:

angular.module('myApp.factories', [])
.factory('$fakeStorage', [
    function(){
        function FakeStorage() {};
        FakeStorage.prototype.setItem = function (key, value) {
            this[key] = value;
        };
        FakeStorage.prototype.getItem = function (key) {
            return typeof this[key] == 'undefined' ? null : this[key];
        }
        FakeStorage.prototype.removeItem = function (key) {
            this[key] = undefined;
        };
        FakeStorage.prototype.clear = function(){
            for (var key in this) {
                if( this.hasOwnProperty(key) )
                {
                    this.removeItem(key);
                }
            }
        };
        FakeStorage.prototype.key = function(index){
            return Object.keys(this)[index];
        };
        return new FakeStorage();
    }
])
.factory('$localstorage', [
    '$window', '$fakeStorage',
    function($window, $fakeStorage) {
        function isStorageSupported(storageName) 
        {
            var testKey = 'test',
                storage = $window[storageName];
            try
            {
                storage.setItem(testKey, '1');
                storage.removeItem(testKey);
                return true;
            } 
            catch (error) 
            {
                return false;
            }
        }
        var storage = isStorageSupported('localStorage') ? $window.localStorage : $fakeStorage;
        return {
            set: function(key, value) {
                storage.setItem(key, value);
            },
            get: function(key, defaultValue) {
                return storage.getItem(key) || defaultValue;
            },
            setObject: function(key, value) {
                storage.setItem(key, JSON.stringify(value));
            },
            getObject: function(key) {
                return JSON.parse(storage.getItem(key) || '{}');
            },
            remove: function(key){
                storage.removeItem(key);
            },
            clear: function() {
                storage.clear();
            },
            key: function(index){
                storage.key(index);
            }
        }
    }
]);

Źródło: https://gist.github.com/jorgecasar/61fda6590dc2bb17e871

Miłego kodowania!

 3
Author: jorgecasar,
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-02-24 21:37:54

Oto rozwiązanie dla AngularJS używając IIFE i wykorzystując fakt, że usługi są singletonami .

Powoduje to, że isLocalStorageAvailable jest ustawiany natychmiast po pierwszym wstrzyknięciu usługi i pozwala uniknąć niepotrzebnego uruchamiania kontroli za każdym razem, gdy potrzebny jest dostęp do lokalnego magazynu.

angular.module('app.auth.services', []).service('Session', ['$log', '$window',
  function Session($log, $window) {
    var isLocalStorageAvailable = (function() {
      try {
        $window.localStorage.world = 'hello';
        delete $window.localStorage.world;
        return true;
      } catch (ex) {
        return false;
      }
    })();

    this.store = function(key, value) {
      if (isLocalStorageAvailable) {
        $window.localStorage[key] = value;
      } else {
        $log.warn('Local Storage is not available');
      }
    };
  }
]);
 2
Author: Pier-Luc Gendreau,
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-03-20 16:43:48

Właśnie stworzyłemrepo , aby zapewnić sessionStorage i localStorage funkcje dla nieobsługiwanych lub wyłączonych przeglądarek.

Obsługiwane przeglądarki

  • IE5+
  • Chrome wszystkie wersje
  • Mozilla wszystkie wersje
  • Yandex wszystkie wersje

Jak to działa

Wykrywa funkcję z typem pamięci.

function(type) {
    var testKey = '__isSupported',
        storage = window[type];
    try {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return true;
    } catch (error) {
        return false;
    }
};

Ustawia StorageService.localStorage na window.localStorage jeśli jest obsługiwany lub tworzy przechowywanie plików cookie. Ustawia StorageService.sessionStorage na window.sessionStorage jeśli jest obsługiwane lub tworzy pamięć w pamięci dla SPA, przechowywanie plików cookie z funkcjami sesion dla non SPA.

 1
Author: Ahmet Can Güven,
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-11-14 07:25:46

Wygląda na to, że Safari 11 zmienia zachowanie, a teraz lokalna pamięć działa w prywatnym oknie przeglądarki. Hura!

Nasza aplikacja internetowa, która kiedyś zawierała przeglądanie prywatne Safari, działa teraz bezbłędnie. Zawsze działał dobrze w trybie przeglądania prywatnego Chrome, który zawsze pozwalał na zapis do pamięci lokalnej.

Jest to udokumentowane w notatkach Apple Safari Technology Preview release notes - i WebKit release notes - dla Wydania 29, które miało miejsce w maju 2017.

Konkretnie:

  • Naprawiono QuotaExceededError podczas zapisywania do localStorage w trybie przeglądania prywatnego lub sesji WebDriver - r215315
 1
Author: karlbecker_com,
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-08-01 16:59:49

Nie używaj go, jeśli nie jest obsługiwany i aby sprawdzić wsparcie, po prostu wywołaj tę funkcję

Udostępnianie w Es6 pełnego odczytu i zapisu localStorage przykład z obsługą sprawdzania

const LOCAL_STORAGE_KEY = 'tds_app_localdata';

const isSupported = () => {
  try {
    localStorage.setItem('supported', '1');
    localStorage.removeItem('supported');
    return true;
  } catch (error) {
    return false;
  }
};


const writeToLocalStorage =
  components =>
    (isSupported ?
      localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(components))
      : components);

const isEmpty = component => (!component || Object.keys(component).length === 0);

const readFromLocalStorage =
  () => (isSupported ? JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || {} : null);

To upewni się, że klucze są ustawione i prawidłowo pobierane we wszystkich przeglądarkach.

 0
Author: Tarandeep Singh,
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-10 18:41:20
var mod = 'test';
      try {
        sessionStorage.setItem(mod, mod);
        sessionStorage.removeItem(mod);
        return true;
      } catch (e) {
        return false;
      }
 0
Author: Naim DOGAN,
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-10-04 11:46:53

Następujący skrypt rozwiązał mój problem:

// Fake localStorage implementation. 
// Mimics localStorage, including events. 
// It will work just like localStorage, except for the persistant storage part. 

var fakeLocalStorage = function() {
  var fakeLocalStorage = {};
  var storage; 

  // If Storage exists we modify it to write to our fakeLocalStorage object instead. 
  // If Storage does not exist we create an empty object. 
  if (window.Storage && window.localStorage) {
    storage = window.Storage.prototype; 
  } else {
    // We don't bother implementing a fake Storage object
    window.localStorage = {}; 
    storage = window.localStorage; 
  }

  // For older IE
  if (!window.location.origin) {
    window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
  }

  var dispatchStorageEvent = function(key, newValue) {
    var oldValue = (key == null) ? null : storage.getItem(key); // `==` to match both null and undefined
    var url = location.href.substr(location.origin.length);
    var storageEvent = document.createEvent('StorageEvent'); // For IE, http://stackoverflow.com/a/25514935/1214183

    storageEvent.initStorageEvent('storage', false, false, key, oldValue, newValue, url, null);
    window.dispatchEvent(storageEvent);
  };

  storage.key = function(i) {
    var key = Object.keys(fakeLocalStorage)[i];
    return typeof key === 'string' ? key : null;
  };

  storage.getItem = function(key) {
    return typeof fakeLocalStorage[key] === 'string' ? fakeLocalStorage[key] : null;
  };

  storage.setItem = function(key, value) {
    dispatchStorageEvent(key, value);
    fakeLocalStorage[key] = String(value);
  };

  storage.removeItem = function(key) {
    dispatchStorageEvent(key, null);
    delete fakeLocalStorage[key];
  };

  storage.clear = function() {
    dispatchStorageEvent(null, null);
    fakeLocalStorage = {};
  };
};

// Example of how to use it
if (typeof window.localStorage === 'object') {
  // Safari will throw a fit if we try to use localStorage.setItem in private browsing mode. 
  try {
    localStorage.setItem('localStorageTest', 1);
    localStorage.removeItem('localStorageTest');
  } catch (e) {
    fakeLocalStorage();
  }
} else {
  // Use fake localStorage for any browser that does not support it.
  fakeLocalStorage();
}

Sprawdza, czy localStorage istnieje i może być używany, a w przypadku negatywnym tworzy fałszywy magazyn lokalny i używa go zamiast oryginalnego localStorage. Proszę dać mi znać, jeśli potrzebujesz więcej informacji.

 -2
Author: Bogdan Mates,
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-07-28 20:42:10