Korzystanie z LocalStorage na iPhonie z iOS 7 powoduje zgłoszenie tego błędu. Rozglądałem się za rezolucją, ale biorąc pod uwagę, że nawet nie przeglądam na osobności, nic nie jest istotne.
Nie rozumiem, dlaczego localStorage byłby domyślnie wyłączony w iOS 7, ale wydaje się, że tak jest? Testowałem również na innych stronach internetowych, ale bez powodzenia. Próbowałem nawet przetestować go przy użyciu tej witryny: http://arty.name/localstorage.html , ale nie wydaje się, żeby coś w ogóle zapisywało z jakiegoś dziwnego powodu.
Czy ktoś miał ten sam problem, tylko czy udało mu się go naprawić? Czy powinienem zmienić metodę przechowywania?
Próbowałem go mocno debugować, przechowując tylko kilka wierszy informacji, ale bezskutecznie. Użyłem standardowej localStorage.setItem()
funkcji do zapisania.
Odpowiedzi:
Może się to zdarzyć, gdy Safari jest w trybie prywatnym. Podczas przeglądania prywatnego pamięć lokalna nie jest w ogóle dostępna.
Jednym z rozwiązań jest ostrzeżenie użytkownika, że aplikacja potrzebuje trybu nieprywatnego do działania.
AKTUALIZACJA: Zostało to naprawione w Safari 11 , więc zachowanie jest teraz dostosowane do innych przeglądarek.
źródło
if( typeof Storage != 'undefined' ) { ... }
) przed próbą załadowania i zapisania informacji, ale otrzymałem ten błąd. Okazuje się, żeStorage
nadal jest zdefiniowane, nawet jeśli nie można go użyć. Używanie try / catch od teraz za każdym razem, gdy korzystam z LocalStorage.Jak wspomniano w innych odpowiedziach, zawsze otrzymasz błąd QuotaExceededError w trybie prywatnej przeglądarki Safari na iOS i OS X, gdy
localStorage.setItem
(lubsessionStorage.setItem
wywoływany jest ).Jednym z rozwiązań jest sprawdzenie try / catch lub Modernizr przy każdym użyciu
setItem
.Jeśli jednak chcesz zastosować podkładkę dystansową, która po prostu globalnie zatrzymuje generowanie tego błędu, aby zapobiec uszkodzeniu reszty kodu JavaScript, możesz użyć tego:
https://gist.github.com/philfreo/68ea3cd980d72383c951
źródło
Korzystam z tej prostej funkcji, która zwraca
true
lubfalse
, w celu przetestowania dostępności localStorage:Teraz możesz przetestować
localStorage.setItem()
dostępność przed użyciem. Przykład:źródło
window.sessionStorage
zastosowanowindow.localStorage
metodę zamiast o nazwieisLocalStorageNameSupported
?HTML local storage provides two objects for storing data on the client: window.localStorage - stores data with no expiration date window.sessionStorage - stores data for one session (data is lost when the browser tab is closed)
sessionStorage
niej ułatwia zarządzanie punktami przerwania, jeśli chcesz przetestować swój rozwój. Nie ma prawdziwego argumentu, który byłby „lepszy”, a tak naprawdę to tylko osobiste preferencje, które popełniają błąd po stronie ostrożności. Najważniejszą rzeczą jest, aby pamiętać, że obasessionStorage
ilocalStorage
są obie implementacje API HTML5 WebStorage.Zdarzyło mi się działać z tym samym problemem w iOS 7 (na niektórych urządzeniach nie ma symulatorów).
Wygląda na to, że Safari w iOS 7 ma niższy limit miejsca, który najwyraźniej jest osiągnięty przez długi dziennik historii.
Chyba najlepszą praktyką będzie złapanie wyjątku.
Projekt Modernizr ma łatwą łatkę, powinieneś spróbować czegoś podobnego: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
źródło
Oto rozszerzone rozwiązanie oparte na powyższej odpowiedzi DrewT, które wykorzystuje pliki cookie, jeśli localStorage nie jest dostępny. Korzysta z biblioteki docCookies Mozilli :
W swoim źródle po prostu użyj:
źródło
Jak już wyjaśniono w innych odpowiedziach, w trybie przeglądania prywatnego Safari zawsze zgłasza ten wyjątek przy próbie zapisania danych
localStorage.setItem()
.Aby to naprawić, napisałem fałszywy localStorage, który naśladuje localStorage, zarówno metody, jak i zdarzenia.
Fałszywy lokalny magazyn: https://gist.github.com/engelfrost/fd707819658f72b42f55
Prawdopodobnie nie jest to dobre ogólne rozwiązanie problemu. To było dobre rozwiązanie dla mojego scenariusza, w którym alternatywą byłoby poważne ponowne zapisanie do już istniejącej aplikacji.
źródło
Aktualizacja (01.11.2016)
Użyłem wspomnianego poniżej AmplifyJS do obejścia tego problemu. Jednak w przypadku przeglądarki Safari w trybie prywatnym wracała do pamięci opartej na pamięci. W moim przypadku nie było to właściwe, ponieważ oznacza to, że pamięć jest czyszczona podczas odświeżania, nawet jeśli użytkownik nadal korzysta z prywatnego przeglądania.
Zauważyłem również wielu użytkowników, którzy zawsze przeglądają w trybie prywatnym na iOS Safari. Z tego powodu lepszym rozwiązaniem dla Safari jest użycie plików cookie (jeśli są dostępne). Domyślnie pliki cookie są nadal dostępne nawet podczas prywatnego przeglądania. Oczywiście są one usuwane podczas wychodzenia z prywatnego przeglądania, ale nie są usuwane podczas odświeżania.
Znalazłem bibliotekę rezerwową lokalnego magazynu . Z dokumentacji:
Uwaga na gotchas:
TL; DR:
Użyj rezerwy lokalnej pamięci masowej (ujednolicony interfejs API z
.getItem(prop)
i.setItem(prop, val)
):Oryginalna odpowiedź
Aby dodać poprzednie odpowiedzi, jednym z możliwych obejść może być zmiana metody przechowywania. Istnieje kilka librairies, takich jak AmplifyJS i PersistJS które mogą pomóc. Obie biblioteki pozwalają na trwałe przechowywanie po stronie klienta przez kilka backendów.
Dla AmplifyJS
For PersistentJS
Oferują warstwę abstrakcji, więc nie musisz się martwić o wybór rodzaju pamięci. Pamiętaj jednak, że mogą istnieć pewne ograniczenia (takie jak limity wielkości) w zależności od rodzaju pamięci. W tej chwili używam AmplifyJS, ale nadal muszę wykonać więcej testów na iOS 7 / Safari / etc. aby sprawdzić, czy to faktycznie rozwiązuje problem.
źródło
W kwietniu 2017 r. Łatka została połączona z Safari, więc była zgodna z innymi przeglądarkami. Zostało to wydane wraz z Safari 11.
https://bugs.webkit.org/show_bug.cgi?id=157010
źródło
To pytanie i odpowiedź pomogły mi rozwiązać konkretny problem z rejestracją nowych użytkowników w Parse.
Ponieważ funkcja signUp (attrs, options) używa pamięci lokalnej do utrwalenia sesji, jeśli użytkownik jest w trybie przeglądania prywatnego, zgłasza „QuotaExceededError: DOM Exception 22: Podjęto próbę dodania do pamięci czegoś, co przekroczyło limit”. wyjątek i funkcje powodzenia / błędu nigdy nie są wywoływane.
W moim przypadku, ponieważ funkcja błędu nigdy nie jest wywoływana, początkowo wydawało się, że jest to problem z odpaleniem zdarzenia kliknięcia w przesłanym pliku lub przekierowaniem zdefiniowanym po pomyślnym zarejestrowaniu.
Dołączenie ostrzeżenia dla użytkowników rozwiązało problem.
Analiza składni SDK JavaScript https://parse.com/docs/js/api/classes/Parse.User.html#methods_signUp
źródło