20

I trying to use Client Side Storage available in HTML5 (localStorage) for Iphone Application , and I'm completely aware of the "QUOTA" associated for localStorage(which is currently 5MB).

Now the problem is for a my application (with no data previously stored) . trying to store the data in localStorage is resulting in QUOTA_EXCEEDED_ERR although the size of the overall data is way less than 5 MB (~ 4Kb to be precise ( found using chrome web inspector in normal browser) )

Can anyone Share some light on this that how a data weigh 4Kb is resulting in QUOTA_EXCEEDED_ERR when the upper limit for the same 5MB

Note that the issue is only occurring for iPhone ,all the browsers and even the iPhone Simulator doesn't prompt with QUOTA_EXCEEDED_ERR error

iPhone currently is picture is iPhone 4 .

Viren
  • 5,812
  • 6
  • 45
  • 98
  • Furthur investigation resulted in that the above error does not replicate in iPhone 3S . so it seem that there is a problem with iOS of iPhone 4 . But something killing me in not believe this because google use localStorage for gmail whick works fine in the above mention iPhone 4 so if there is a problem with iOS of iPhone 4 how come the localStorage work for gmail then. Can anyone share light on this . – Viren Feb 14 '12 at 05:56
  • Pasting the Code that causing the above error – Viren Feb 16 '12 at 09:38
  • 2
    Check my answer below. It's likely that either you're phone has private browsing enabled, or you are using the wrong setter for local storage – JoeCortopassi Feb 16 '12 at 21:34
  • 1
    Use [a feature detect that tests for this specific issue](https://github.com/download/storage-available). If storage is not available, consider shimming localStorage with [memoryStorage](https://github.com/download/memorystorage). *disclaimer: I am the author of the linked packages* – Stijn de Witt Jan 27 '17 at 14:25

5 Answers5

29

Go into Settings->Safari and check to see if private browsing is on. If it is, local storage will not be able to store anything. Here's some basic code to check local storage for you:

if (!!window.localStorage) 
{
    localStorage.setItem(key, val);
};

Also, how are you setting it? Are you using localStorage.setItem(key, val), or trying localStorage(key, val)? You're problem might be coming from setting it incorrectly

JoeCortopassi
  • 5,083
  • 7
  • 37
  • 65
  • 2
    ,Yes that it you were right the issue is w.r.s.t private browsing enabled in iPhone disabling it worked fine but can share some light on why the same work in emulator with private browsing enabled and how localStorage works for Gmail on iPhone even though private browsing in "enabled" , Any Way but the answer did worked thanks for the help – Viren Feb 17 '12 at 14:48
  • 1
    Wow, thanks a lot for this answer, I would never have looked in this direction! – Martijn de Milliano Feb 01 '13 at 21:22
  • 3
    You're right that localStorage can't store anything in Safari private mode, but the code snippet won't work for detecting this. `window.localStorage` returns a Storage object even when Safari is in private mode. – Mikel Mar 19 '14 at 22:54
  • Seeing the same behavior while using iphone 4s and mobile safari (no private browsing). Can't set anything beyond 2.5MB. Don't know what could be causing this, using a library: http://amplifyjs.com/api/store/ – newshorts Jun 18 '14 at 22:44
19

I had the same issue and JoeCortopassi is only partly right: it is caused by private browsing being enabled. The code provided in that answer does not help much though. When I tested on iPad Safari(ios5) I got

console.log(!!window.localStorage); // true

As soon as I try to set a value, I get an exception:

localStorage.setItem("test", "test") // Exception 22 is thrown

So to accurately test for local storage support, it is necessary to try and set a value in local storage, for example:

var localStorageSupported = function() {
  try {
    localStorage.setItem("test", "test");
    localStorage.removeItem("test");
    return true;
  } catch(e){
    return false;
  }
}
wosis
  • 1,209
  • 10
  • 14
8

The fact is that using private browsing mode on Safari for iOS < 6 does not empty window.localStorage and window.sessionStorage and therefore checking !!window.localStorage or !!window.sessionStorage won't be enough, and whatever you call from those components will just fail, throwing this QUOTA_EXCEEDED_ERR error.

On those platforms, the private mode seems to set the quota to zero. That's the reason why, to really test those features, the same way Modernizr does, you'll have to wrap it inside a try...catch statement.

Modernizr code :

var mod = 'modernizr';
/*...*/
tests['localstorage'] = function() {
    try {
        localStorage.setItem(mod, mod);
        localStorage.removeItem(mod);
        return true;
    } catch(e) {
        return false;
    }
};

We have to trust web APIs, but quite carefully.

atondelier
  • 2,424
  • 15
  • 11
3

Try deleting the value before setting a new one:

localStorage.removeItem(key);
localStorage.setItem(key, val);

See also this question, as it looks similar.

Community
  • 1
  • 1
Laurent Etiemble
  • 27,111
  • 5
  • 56
  • 81
3

Local storage quota is tied to domain, if you have other pages that use the data storage they may fill it up. Iterate the keys to find out whats there in the storage when you get the exception.

try {
   // try to insert storage here
} catch ( err ) {
   for ( var i =0; i < storage.length ; i++ ) {
       console.log ( storage.key( i ) )
    }
}
Teemu Ikonen
  • 11,861
  • 4
  • 22
  • 35
  • @Temmu , That not it infact trying to store a simple key value pair on a empty localStorage (for the first time like this) localStorage.setItem("error","QUOTA_EXCEEDED_ERR") result in above error certainly the value stored is far less than 5MB and even 4KB – Viren Feb 16 '12 at 05:28
  • I mean that its possible that there is some other page or webapp served from same domain than your app and its that other app that is filling the storage. – Teemu Ikonen Feb 16 '12 at 22:11
  • @Temmu , That only page in application where localStorage in implemented – Viren Feb 17 '12 at 07:06