marcuswestin / store.js

Cross-browser storage for all use cases, used across the web.
MIT License
14.02k stars 1.33k forks source link

QuotaExceededError on iOS with Safari and the newest releases not available from cdnjs #232

Open kireerik opened 7 years ago

kireerik commented 7 years ago

QuotaExceededError: The quota has been exceeded.

Also newest releases not available from cdnjs.

camloken commented 7 years ago

Safari has both localStorage and sessionStorage in private browsing mode, however, they set the quota limit to 0, so you can't actually store anything. The way around this is to test if you can actually set an item using localStorage.

let hasLocalStorage = false;

if (localStorage) {
  try {
    const x = 'testStorage';
    localStorage.setItem(x, x);
    localStorage.removeItem(x);
    hasLocalStorage = true;
  } catch (e) {
    hasLocalStorage = false;
  }
}

Same goes for sessionStorage. If either one return false (they will in Safari private browsing), create a variable and store your data there. Here is a full example of what I did on a similar project below (I'm only testing for localStorage):

const data = {};
let hasLocalStorage = false;

if (localStorage) {
  try {
    const x = 'testStorage';
    localStorage.setItem(x, x);
    localStorage.removeItem(x);
    hasLocalStorage = true;
  } catch (e) {
    hasLocalStorage = false;
  }
}

class StorageUtilities {
  // set
  setItem(key, value) {
    if (hasLocalStorage) {
      localStorage.setItem(key, value);
    } else {
      data[key] = value;
   }
  }

  // get
  getItem(key) {
    if (hasLocalStorage) {
      return localStorage.getItem(key);
    } else {
      return data[key];
    }
  }

  // remove
  removeItem(key) {
    if (hasLocalStorage) {
      localStorage.removeItem(key);
    } else {
      data[key] = null;
    }
  }
}

const storageUtilities = new StorageUtilities();

export default storageUtilities;

Someone feel free to implement a similar solution here.

dijs commented 6 years ago

I just came across this error today... I thought store.js was supposed to help deal with these issues... Does anyone have an idea how to handle this problem with store.js

nbubna commented 6 years ago

@dijs , what version of Safari? I just tried getting the old quota error on my Mac's Safari 11.0.3 and localStorage was working fine in private mode. I have been under the impression for a few months that Apple had fixed this problem.

dijs commented 6 years ago

Here is my sentry error:

screen shot 2018-03-05 at 7 40 28 pm
nbubna commented 6 years ago

This works in private mode for me on my iPhone (11.2.6):

https://jsbin.com/nofunigoya/edit?js,output

Also works in Safari Private on my Mac.

dijs commented 6 years ago

So if this isn't the iOS bug, it must be legitimately full? Or can you think of another reason why this would be throwing...

Even so, I thought store.js would catch this error and handle the storage with a fallback.

nbubna commented 6 years ago

I don't know of support for that in this library. https://github.com/nbubna/store has an "overflow" extension that provides non-persistent storage when you hit the quota, if that's of interest.

nbubna commented 6 years ago

I'm sure it's possible to write such an extension for this store library too.

dijs commented 6 years ago

Thanks for the suggestions.