Using LocalStorage on iPhone with iOS 7 throws this error. I've been looking around for a resolvant, but considering I'm not even browsing in private, nothing is relevant.

I don't understand why localStorage would be disabled by default in iOS 7, but it seems it is? I've tested on other websites as well, but with no luck. I even tried testing it using this website: http://arty.name/localstorage.html, but it doesn't seem like it's saving anything at all for some weird reason.

Has anyone had the same problem, only they've had luck fixing it? Should I switch my storage method?

I tried hard-debugging it by only storing a few lines of information, but to no avail. I used the standard localStorage.setItem() function to save.

It usually means you tried to store something with a size that exceeded available storage space. What browser are you using (Safari, Chrome, etc.)? Can you share a little more of the code you have been using and if possible the data you're trying to store.
– user1693593Jan 16 '14 at 21:32

3

This should be considered as a bug or issue on the Safari side. It does not make sense that you can not use localStorage in incognito mode...
– Maksim LuzikFeb 1 '16 at 12:09

I can confirm this has been fixed in Safari iOS 11. Tested Private browsing + sessionStorage.setItem() then sessionStorage.getItem() successfully on iPhone6 and iPhone8.
– Kevin GaudinOct 17 '17 at 12:49

+1 fixed my issue. I was checking for the existence of LocalStorage (if( typeof Storage != 'undefined' ) { ... }) before trying to load and save information but getting this error. Turns out Storage is still defined even when it's unusable. Using try/catch from now on whenever I use LocalStorage.
– stevendesuSep 15 '14 at 13:36

Thanks! Weird error by safari. Should have been more informative. :D
– Sunny R GuptaFeb 19 '16 at 14:24

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

Have I missed something? Why is window.sessionStorage been used instead of window.localStorage for a method called isLocalStorageNameSupported?
– ItharMar 29 '16 at 9:37

@lthar - see the documentation here: w3schools.com/html/html5_webstorage.asp Most importantly this part: 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)
– DrewTMar 29 '16 at 18:05

@DrewT, but what's the difference in this situation if you remove your test key? It doesn't matter where I will store my test key if I am going to delete it. Am I wrong? Why is the session storage better that the local one?
– Vladyslav TurakSep 6 '16 at 9:33

1

@TurakVladyslav you're right there is really no difference here except that using sessionStorage makes it more manageable for setting breakpoints if you want to test your development. There is no true argument for which is "better" and it's really just a personal preference here that errs on the side of caution. The main thing to note is that both sessionStorage and localStorage are both implementations of the HTML5 webstorage API.
– DrewTSep 6 '16 at 16:26

What exactly does it fix? It doesn't persist anything, so what's the point?
– Esben Skov PedersenFeb 26 '17 at 17:56

1

It "fixes" Safari when in private browsing mode. (This is not clear in my answer, thanks for pointing that out. I'll edit my answer). Nothing is supposed to be persisted when in private browsing mode regardless, so not persisting is not a relevant issue here. What this fixed for me was to allow users to run an already existing application, without major re-writes, even when in Private Browsing mode in Safari.
– Josef EngelfrostMar 1 '17 at 11:15

Update (2016-11-01)

I was using AmplifyJS mentioned below to work around this issue. However, for Safari in Private browsing, it was falling back to a memory-based storage. In my case, it was not appropriate because it means the storage is cleared on refresh, even if the user is still in private browsing.

Also, I have noticed a number of users who are always browsing in Private mode on iOS Safari. For that reason, a better fallback for Safari is to use cookies (if available). By default, cookies are still accessible even in private browsing. Of course, they are cleared when exiting the private browsing, but they are not cleared on refresh.

Purpose

With browser settings like "Private Browsing" it has become a problem to rely on a working window.localStorage, even in newer browsers. Even though it may exist, it will throw exceptions when trying to use setItem or getItem. This module will run appropriate checks to see what browser storage mechanism might be available, and then expose it. It uses the same API as localStorage so it should work as a drop-in replacement in most cases.

Beware of the gotchas:

CookieStorage has storage limits. Be careful here.

MemoryStorage will not persist between page loads. This is more or less a stop-gap to prevent page crashes, but may be sufficient for websites that don't do full page loads.

TL;DR:

Original answer

To add upon previous answers, one possible workaround would be to change the storage method. There are a few librairies such as AmplifyJS and PersistJS which can help. Both libs allow persistent client-side storage through several backends.

For AmplifyJS

localStorage

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+

userData

IE 5 - 7

userData exists in newer versions of IE as well, but due to quirks in IE 9's implementation, we don't register userData if localStorage
is supported.

memory

An in-memory store is provided as a fallback if none of the other storage types are available.

For PersistentJS

flash: Flash 8 persistent storage.

gears: Google Gears-based persistent storage.

localstorage: HTML5 draft storage.

globalstorage: HTML5 draft storage (old spec).

ie: Internet Explorer userdata behaviors.

cookie: Cookie-based persistent storage.

They offer an abstraction layer so you don't have to worry about choosing the storage type. Keep in mind there might be some limitations (such as size limits) depending on the storage type though. Right now, I am using AmplifyJS, but I still have to do some more testing on iOS 7/Safari/etc. to see if it actually solves the problem.

Editor John: I realize you and Jonathan Alzetta are probably the same account and you're just trying to improve your answer, but if so you should really log-in as Jonathan Alzetta and edit this answer, and then it won't go through the review queue. Recover your account if you need to.
– DavidSNov 1 '16 at 16:38

This question and answer helped me solve a specific problem with signing up new users in Parse.

Because the signUp( attrs, options ) function uses local storage to persist the session, if a user is in private browsing mode it throws the "QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota." exception and the success/error functions are never called.

In my case, because the error function is never called it initially appeared to be an issue with firing the click event on the submit or the redirect defined on success of sign up.

Signs up a new user with a username (or email) and password. This will create a new Parse.User on the server, and also persist the session in localStorage so that you can access the user using {@link #current}.