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”.


133

Moja aplikacja internetowa ma błędy javascript podczas przeglądania prywatnego safari na iOS:

JavaScript: błąd

nieokreślony

QUOTA_EXCEEDED_ERR: DOM Wyjątek 22: Podjęto próbę dodania czegoś do magazynu ...

mój kod:

localStorage.setItem('test',1)

Użyj funkcji, która wykrywa testy pod kątem tego konkretnego problemu . Jeśli pamięć nie jest dostępna, rozważ shimowanie localStorage za pomocą memoryStorage . zastrzeżenie: jestem autorem powiązanych pakietów
Stijn de Witt

4
Cześć, pomagam w utrzymaniu safaridriver. Ten problem to występujący od dawna błąd w oprogramowaniu WebKit, który został niedawno naprawiony. Lokalna pamięć masowa i pamięć sesji działają teraz w przeglądarce Safari 10.1 i nowszych. Ta poprawka dotyczy normalnego trybu przeglądania prywatnego i trybu automatyzacji (używanego przez WebDriver).
Brian Burg

Odpowiedzi:


183

Najwyraźniej jest to zamierzone. Gdy Safari (OS X lub iOS) jest w trybie przeglądania prywatnego, wygląda na localStorageto, że jest dostępne, ale próba wywołania setItemzgłasza 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 okna nadal uwidacznia się localStoragew globalnej przestrzeni nazw, ale podczas wywołania setItemzgłaszany jest ten wyjątek. Wszelkie wezwania do removeItemsą ignorowane.

Uważam, że najprostszą poprawką (chociaż nie testowałem jeszcze tej przeglądarki) byłaby zmiana funkcji, isLocalStorageNameSupported()aby sprawdzić, czy 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;
    }
}

1
Niekoniecznie musi to być spowodowane trybem incognito ... chociaż wydaje mi się, że OP nie chciał przechowywać kilku megabajtów danych;)
Christoph

5
Zapoznaj się z tym streszczeniem przedstawiającym krótką historię wykrywania lokalnego magazynu przez Paula Irisha.
Mottie,

4
W przypadku, gdy localStorage nie będzie działać w Safari, czy przechowywanie wszystkiego w plikach cookie jest kolejną najlepszą opcją?
Will Hitchcock

5
Podobnie jak w przypadku Paula Irisha, proponuję zmienić return localStorageName in win && win[localStorageName];na return true. Następnie masz funkcję, która bezpiecznie zwraca wartość true lub false w zależności od dostępności localStorage. Na przykład:if (isLocalStorageNameSupported()) { /* You can use localStorage.setItem */ } else { /* you can't use localStorage.setItem */ }
DrewT

1
Zweryfikowano, że problem dotyczy nie tylko okna prywatnego, ale także normalnego okna safari.
codemirror

38

Poprawka zamieszczona pod powyższym linkiem nie działa dla mnie. To zrobiło:

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


20
Czy jest jakiś szczególny powód, dla którego (i @KingKongFrog) używasz window.sessionStorage do wykrywania, czy możesz pisać do localStorage, czy też jesteśmy w dziwnym cyklu literówek kopiuj-wklej?
Yetti

@Yetti Jeśli zauważyłeś literówkę, dlaczego nie poprawisz jej w edycji lub w komentarzu? O ile mi wiadomo, window.sessionStorageto prawda. Z pewnością działa w moim kodzie. Wskaż sposób rozwiązania problemu, o którym wiesz.
Nowokaina

7
@Novocaine Mój komentarz wskazywał, że używają sessionStorage w funkcji, która istnieje do sprawdzania obsługi localStorage. Tak, prawdopodobnie nadal będzie działać, ale jak napisano, nazwa funkcji wprowadza w błąd co do tego, co jest faktycznie testowane. Wolałem komentować niż edytować, ponieważ myślałem, że czegoś mi brakuje i miałem nadzieję, że nauczę się od tych gości. Niestety, nie odpowiedzieli ani nie wprowadzili korekty, więc oto jesteśmy.
Yetti

3
@Yetti Dziękuję za wyjaśnienie. Teraz rozumiem, o co ci chodziło. ; -]
Novocaine

2
@DawsonToth nie, ponieważ wywołałem funkcję isLocalStorageNameSupportedi sprawdzałem window.sessionStorage. Ten sam efekt końcowy, ale był trochę zagmatwany. Odpowiedź została zredagowana w celu wyjaśnienia.
cyberwombat

25

Jak wspomniano w innych odpowiedziach, zawsze otrzymasz błąd QuotaExceededError w trybie przeglądarki prywatnej Safari w systemie iOS i OS X, gdy zostanie wywołany localStorage.setItem(lub sessionStorage.setItem).

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

Jeśli jednak potrzebujesz podkładki, która po prostu globalnie zapobiega zgłaszaniu tego błędu, aby zapobiec uszkodzeniu reszty JavaScript, możesz użyć tego:

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

11

W moim kontekście właśnie opracowałem abstrakcję klas. Po uruchomieniu aplikacji sprawdzam, czy działa localStorage, wywołując metodę getStorage () . Ta funkcja zwraca również:

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

W moim kodzie nigdy nie dzwonię bezpośrednio do localStorage. Wzywam cusSto globalny var miałem zainicjowane przez wywołanie getStorage () .

W ten sposób działa z przeglądaniem prywatnym lub określonymi 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();

2
Dzięki, Pierre, twoja odpowiedź mnie zainspirowała. Skończyło się na tym, że zapakowałem to wszystko w ładny moduł zwany memorystorage . Oczywiście Open Source. W przypadku innych osób z tym samym problemem sprawdź, czy może ci to pomóc.
Stijn de Witt

Ha. Zrobiłem to samo (niezależnie). Nadal jednak używaj zmiennej localStorage (przynajmniej w Safari nie możesz nadpisać zmiennej localStorage (jest to „tylko do odczytu”), ale możesz ponownie przypisać setItem / removeItem / getItem).
Ruben Martinez Jr.

@StijndeWitt, jak mogę uzyskać dostęp do moich wartości przechowywania na innych stronach? Na przykład mam to w moim helper.php var store = MemoryStorage ('my-app'); store.setItem ('myString', 'Hello MemoryStorage!'); Chcę uzyskać dostęp do wartości myString w lecture.php. Próbowałem zainicjować przechowywanie pamięci na stronie, ale nadal pokazuje ona pusty obiekt.
user1149244

Adres @ user1149244 Memorystorage jest lokalny dla strony. Symuluje interfejs API usługi Web Storage i jako taki może służyć jako rezerwa, gdy localStorage i sessionStorage nie są dostępne. Jednak dane zostaną zachowane tylko w pamięci strony (stąd nazwa). Jeśli chcesz, aby dane były przechowywane na różnych stronach, mogą Ci pomóc pliki cookie. Ale ilość danych, które można przechowywać, jest bardzo ograniczona. Poza tym niewiele można zrobić.
Stijn de Witt,

2
@ user1149244 Czy to rzekomo nie przechowuje wartości w przeglądarce? Nie, nie może. Istnieją 3 sposoby przechowywania informacji po stronie klienta z jednej strony odświeżanej na drugą: pliki cookie, sessionStorage / localStorage i IndexedDB. Ostatnie dwa są stosunkowo nowe. sessionStorage i localStorage są szeroko obsługiwane, więc możesz ich używać praktycznie wszędzie. z wyjątkiem trybu przeglądania prywatnego , o co chodzi w tym problemie. Programy się zepsuły, ponieważ nie było tam pamięci. memorystorage zapewnia po prostu rezerwę, która zawsze działa na stronie, ale nie może w rzeczywistości zapisać danych. To jest kikut. Ale bez błędu.
Stijn de Witt,

5

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

Nasza aplikacja internetowa, która wcześniej nie działała podczas przeglądania prywatnego w Safari, teraz działa bez zarzutu. Zawsze działało dobrze w trybie przeglądania prywatnego Chrome, który zawsze pozwalał na zapisywanie w pamięci lokalnej.

Jest to udokumentowane w informacjach o wersji Safari Technology Preview firmy Apple - oraz w informacjach o wydaniu WebKit - dla wersji 29, która miała miejsce w maju 2017 r.

Konkretnie:

  • Naprawiono błąd QuotaExceededError podczas zapisywania do localStorage w trybie przeglądania prywatnego lub sesji WebDriver - R215315

4

Aby rozwinąć odpowiedzi innych osób, oto kompaktowe rozwiązanie, które nie ujawnia / nie dodaje żadnych nowych zmiennych. Nie obejmuje wszystkich baz, ale powinien odpowiadać większości osób, które chcą, aby aplikacja z jedną stroną pozostała funkcjonalna (pomimo braku trwałości danych po ponownym zał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 = {};
        };
    }
})();

3

Miałem ten sam problem używając frameworka Ionic (Angular + Cordova). Wiem, że to nie rozwiązuje problemu, ale jest to kod dla Angular Apps oparty na powyższych odpowiedziach. Będziesz mieć 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

Życzymy udanego kodowania!


1
Chociaż to nie odpowiada na pytanie, jest to pierwsza rzecz, która pojawiła się, gdy wyszukałem ten problem w Google. Następnym krokiem byłoby poszukiwanie rozwiązania dla Angulara, ale dzięki temu komentarzowi nie muszę nigdzie indziej iść. Więc może nie odpowiadać bezpośrednio na pytanie, ale był świetny dla mnie i prawdopodobnie dla innych!
Leonard

2

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

Powoduje to, isLocalStorageAvailableże jest ustawiana natychmiast po pierwszym wstrzyknięciu usługi i pozwala uniknąć niepotrzebnego przeprowadzania sprawdzania za każdym razem, gdy trzeba uzyskać dostęp do pamięci lokalnej.

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

1

Właśnie utworzyłem to repozytorium, aby zapewnić sessionStoragei localStoragefunkcje 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;
    }
};

Zestawy StorageService.localStoragedo window.localStoragejeśli jest obsługiwany lub tworzy przechowywania cookie. Zestawy StorageService.sessionStoragedo window.sessionStoragejeśli jest obsługiwany lub tworzy w pamięci do przechowywania, magazynowania SPA ciasteczka z funkcji Sesión za nieprzestrzeganie SPA.


1
Dzięki, twoja biblioteka bardzo pomogła!
Mathieu

1

Oto wersja usługi Angular2 + dla alternatywnego przechowywania pamięci, którą możesz po prostu wstrzyknąć do swoich komponentów, w oparciu o odpowiedź Pierre'a Le Roux.

import { Injectable } from '@angular/core';

// Alternative to localstorage, memory
// storage for certain browsers in private mode
export class LocalStorageAlternative {
    private  structureLocalStorage = {};

    setItem(key: string, value: string): void {
        this.structureLocalStorage[key] = value;
    }

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

    removeItem(key: string): void {
        this.structureLocalStorage[key] = undefined;
    }
}

@Injectable()
export class StorageService {
    private storageEngine;

    constructor() {
        try {
            localStorage.setItem('storage_test', '');
            localStorage.removeItem('storage_test');
            this.storageEngine = localStorage;
        } catch (err) {
            this.storageEngine = new LocalStorageAlternative();
        }
    }

    setItem(key: string, value: string): void {
        this.storageEngine.setItem(key, value);
    }

    getItem(key: string): string {
        return this.storageEngine.getItem(key);
    }

    removeItem(key: string): void {
        this.storageEngine.removeItem(key);
    }

}

0

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łny odczyt i zapis localStorage Przykład z kontrolą wsparcia

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

Zapewni to prawidłowe ustawienie i pobieranie kluczy we wszystkich przeglądarkach.


0

Stworzyłem łatkę na ten problem. Po prostu sprawdzam, czy przeglądarka obsługuje localStorage lub sessionStorage, czy nie. Jeśli nie, to mechanizm przechowywania będzie Cookie. Ale negatywną stroną jest to, że Cookie ma bardzo małą pamięć :(

function StorageEngine(engine) {
    this.engine = engine || 'localStorage';

    if(!this.checkStorageApi(this.engine)) {
        // Default engine would be alway cooke
        // Safari private browsing issue with localStorage / sessionStorage
        this.engine = 'cookie';
    }
}

StorageEngine.prototype.checkStorageApi = function(name) {
    if(!window[name]) return false;
    try {
        var tempKey = '__temp_'+Date.now();
        window[name].setItem(tempKey, 'hi')
        window[name].removeItem(tempKey);
        return true;
    } catch(e) {
        return false;
    }
}

StorageEngine.prototype.getItem = function(key) {
    if(['sessionStorage', 'localStorage'].includes(this.engine)) {
        return window[this.engine].getItem(key);
    } else if('cookie') {
        var name = key+"=";
        var allCookie = decodeURIComponent(document.cookie).split(';');
        var cval = [];
        for(var i=0; i < allCookie.length; i++) {
            if (allCookie[i].trim().indexOf(name) == 0) {
                cval = allCookie[i].trim().split("=");
            }   
        }
        return (cval.length > 0) ? cval[1] : null;
    }
    return null;
}

StorageEngine.prototype.setItem = function(key, val, exdays) {
    if(['sessionStorage', 'localStorage'].includes(this.engine)) {
        window[this.engine].setItem(key, val);
    } else if('cookie') {
        var d = new Date();
        var exdays = exdays || 1;
        d.setTime(d.getTime() + (exdays*24*36E5));
        var expires = "expires="+ d.toUTCString();
        document.cookie = key + "=" + val + ";" + expires + ";path=/";
    }
    return true;
}


// ------------------------
var StorageEngine = new StorageEngine(); // new StorageEngine('localStorage');
// If your current browser (IOS safary or any) does not support localStorage/sessionStorage, then the default engine will be "cookie"

StorageEngine.setItem('keyName', 'val')

var expireDay = 1; // for cookie only
StorageEngine.setItem('keyName', 'val', expireDay)
StorageEngine.getItem('keyName')

0

Przyjęta odpowiedź wydaje się nieadekwatna w kilku sytuacjach.

Aby sprawdzić, czy obsługiwane localStoragelub sessionStoragesą obsługiwane, używam następującego fragmentu z MDN .

function storageAvailable(type) {
    var storage;
    try {
        storage = window[type];
        var x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored
            (storage && storage.length !== 0);
    }
}

Użyj tego fragmentu kodu w ten sposób i wróć do, na przykład, pliku cookie:

if (storageAvailable('localStorage')) {
  // Yippee! We can use localStorage awesomeness
}
else {
  // Too bad, no localStorage for us
  document.cookie = key + "=" + encodeURIComponent(value) + expires + "; path=/";
}

Zrobiłem pakiet fallbackstorage , który używa tego fragmentu kodu do sprawdzenia dostępności magazynu i powrotu do ręcznie zaimplementowanego MemoryStorage.

import {getSafeStorage} from 'fallbackstorage'

getSafeStorage().setItem('test', '1') // always work

-1
var mod = 'test';
      try {
        sessionStorage.setItem(mod, mod);
        sessionStorage.removeItem(mod);
        return true;
      } catch (e) {
        return false;
      }

1
Może chcesz dodać kilka słów wyjaśnienia?
bogl

-2

Poniższy 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, aw negatywnym przypadku tworzy fałszywą lokalną pamięć masową i używa jej zamiast oryginalnego localStorage. Daj mi znać, jeśli potrzebujesz dodatkowych informacji.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.