HTML5 localStorage.setItem is not working on iOS 8 - Safari mobile

Mandy picture Mandy · May 5, 2015 · Viewed 11.4k times · Source

localStorage.setItem is not working on mobile iOS 8.3.

Does anybody experience this problem?
Here is the code:

var storage = window.localStorage;
storage.setItem('test',45);
alert(storage.getItem('test'));

Answer

J Little picture J Little · Sep 20, 2016

In the past, we could use something like:

if ('localStorage' in window && window.localStorage !== null) {
    alert('can use');
}else{
    alert('cannot use');
}

or

if (localStorage === undefined) {... }

However, in iOS 8.3+, when the user disables cookies, this code throws an unhandled JavaScript error. And when the user goes into private browsing mode, that same error message appears when you try to write to localStorage.

SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.



Workaround

To avoid unwanted JavaScript errors due to this particular behavior of iOS, one suggestion is to enclose it within try catch blocks. (at least for the time being)

try{
  if ('localStorage' in window && window.localStorage !== null) {
    localStorage.setItem('testLocalStorage', 'testLocalStorage');
    if (localStorage.getItem('testLocalStorage') !== 'testLocalStorage') {
        localStorage.removeItem('testLocalStorage');
        //for private browsing, error is thrown before even getting here
        alert('can read CANNOT write'); 
    }else{
        localStorage.removeItem('testLocalStorage');
        alert('can use');
    }
  }else{
    alert('CANNOT use');
  }
}catch(ex){
  alert('CANNOT use reliably');
}

Note: This is not a suggestion to use alerts in your actual codes. It is just for a quick illustration.



Possible Shortform

try {
    localStorage.setItem('testLocalStorage', 'testLocalStorage');
    localStorage.removeItem('testLocalStorage');
    alert('supported');
} catch(ex) {
    alert('unsupported');
}



What can we use instead

For scenarios where localStorage is not supported, possible alternatives include server sessions (based on URL parameters if cookies are not supported), or window.name variable to store the serialized data.

Or if you design and build as a Single Page App, perhaps you do not need to store data in the global namespace at all.