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)
javascript
html
local-storage
leiyonglin
źródło
źródło
Odpowiedzi:
Najwyraźniej jest to zamierzone. Gdy Safari (OS X lub iOS) jest w trybie przeglądania prywatnego, wygląda na
localStorage
to, że jest dostępne, ale próba wywołaniasetItem
zgłasza wyjątek.Dzieje się tak, że obiekt okna nadal uwidacznia się
localStorage
w globalnej przestrzeni nazw, ale podczas wywołaniasetItem
zgłaszany jest ten wyjątek. Wszelkie wezwania doremoveItem
są 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
źródło
return localStorageName in win && win[localStorageName];
nareturn 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 */ }
Poprawka zamieszczona pod powyższym linkiem nie działa dla mnie. To zrobiło:
Pochodzi z http://m.cg/post/13095478393/detect-private-browsing-mode-in-mobile-safari-on-ios5
źródło
window.sessionStorage
to prawda. Z pewnością działa w moim kodzie. Wskaż sposób rozwiązania problemu, o którym wiesz.isLocalStorageNameSupported
i sprawdzałemwindow.sessionStorage
. Ten sam efekt końcowy, ale był trochę zagmatwany. Odpowiedź została zredagowana w celu wyjaśnienia.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
(lubsessionStorage.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
źródło
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ż:
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
źródło
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:
źródło
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).
źródło
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:
Źródło: https://gist.github.com/jorgecasar/61fda6590dc2bb17e871
Życzymy udanego kodowania!
źródło
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.źródło
Właśnie utworzyłem to repozytorium, aby zapewnić
sessionStorage
ilocalStorage
funkcje dla nieobsługiwanych lub wyłączonych przeglądarek.Obsługiwane przeglądarki
Jak to działa
Wykrywa funkcję z typem pamięci.
Zestawy
StorageService.localStorage
dowindow.localStorage
jeśli jest obsługiwany lub tworzy przechowywania cookie. ZestawyStorageService.sessionStorage
dowindow.sessionStorage
jeśli jest obsługiwany lub tworzy w pamięci do przechowywania, magazynowania SPA ciasteczka z funkcji Sesión za nieprzestrzeganie SPA.źródło
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.
źródło
Nie używaj go, jeśli nie jest obsługiwany, i aby sprawdzić wsparcie, po prostu wywołaj tę funkcję
źródło
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ęć :(
źródło
Przyjęta odpowiedź wydaje się nieadekwatna w kilku sytuacjach.
Aby sprawdzić, czy obsługiwane
localStorage
lubsessionStorage
są obsługiwane, używam następującego fragmentu z MDN .Użyj tego fragmentu kodu w ten sposób i wróć do, na przykład, pliku cookie:
Zrobiłem pakiet fallbackstorage , który używa tego fragmentu kodu do sprawdzenia dostępności magazynu i powrotu do ręcznie zaimplementowanego MemoryStorage.
źródło
źródło
Poniższy skrypt rozwiązał mój problem:
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.
źródło