html5 localStorage error with Safari: “QUOTA_EXCEE

2019-01-02 19:39发布

My webapp have javascript errors in ios safari private browsing:

JavaScript:error

undefined

QUOTA_EXCEEDED_ERR:DOM Exception 22:An attempt was made to add something to storage...

my code:

localStorage.setItem('test',1)

12条回答
与风俱净
2楼-- · 2019-01-02 20:33
var mod = 'test';
      try {
        sessionStorage.setItem(mod, mod);
        sessionStorage.removeItem(mod);
        return true;
      } catch (e) {
        return false;
      }
查看更多
低头抚发
3楼-- · 2019-01-02 20:34

Here's a solution for AngularJS using an IIFE and leveraging the fact that services are singletons.

This results in isLocalStorageAvailable being set immediately when the service is first injected and avoids needlessly running the check every time local storage needs to be accessed.

angular.module('app.auth.services', []).service('Session', ['$log', '$window',
  function Session($log, $window) {
    var isLocalStorageAvailable = (function() {
      try {
        $window.localStorage.world = 'hello';
        delete $window.localStorage.world;
        return true;
      } catch (ex) {
        return false;
      }
    })();

    this.store = function(key, value) {
      if (isLocalStorageAvailable) {
        $window.localStorage[key] = value;
      } else {
        $log.warn('Local Storage is not available');
      }
    };
  }
]);
查看更多
美炸的是我
4楼-- · 2019-01-02 20:35

I just created this repo to provide sessionStorage and localStorage features for unsupported or disabled browsers.

Supported browsers

  • IE5+
  • Chrome all versions
  • Mozilla all versions
  • Yandex all versions

How it works

It detects the feature with the storage type.

function(type) {
    var testKey = '__isSupported',
        storage = window[type];
    try {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return true;
    } catch (error) {
        return false;
    }
};

Sets StorageService.localStorage to window.localStorage if it is supported or creates a cookie storage. Sets StorageService.sessionStorage to window.sessionStorage if it is supported or creates a in memory storage for SPA, cookie storage with sesion features for non SPA.

查看更多
路过你的时光
5楼-- · 2019-01-02 20:36

Don't use it if not supported and to check support just call this function

sharing in Es6 full read and write localStorage Example with support check

const LOCAL_STORAGE_KEY = 'tds_app_localdata';

const isSupported = () => {
  try {
    localStorage.setItem('supported', '1');
    localStorage.removeItem('supported');
    return true;
  } catch (error) {
    return false;
  }
};


const writeToLocalStorage =
  components =>
    (isSupported ?
      localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(components))
      : components);

const isEmpty = component => (!component || Object.keys(component).length === 0);

const readFromLocalStorage =
  () => (isSupported ? JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || {} : null);

This will make sure your keys are set and retrieved properly on all browsers.

查看更多
梦该遗忘
6楼-- · 2019-01-02 20:37

It seems that Safari 11 changes the behavior, and now local storage works in a private browser window. Hooray!

Our web app that used to fail in Safari private browsing now works flawlessly. It always worked fine in Chrome's private browsing mode, which has always allowed writing to local storage.

This is documented in Apple's Safari Technology Preview release notes - and the WebKit release notes - for release 29, which was in May 2017.

Specifically:

  • Fixed QuotaExceededError when saving to localStorage in private browsing mode or WebDriver sessions - r215315
查看更多
余生无你
7楼-- · 2019-01-02 20:38

Apparently this is by design. When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage is available, but trying to call setItem throws an exception.

store.js line 73
"QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."

What happens is that the window object still exposes localStorage in the global namespace, but when you call setItem, this exception is thrown. Any calls to removeItem are ignored.

I believe the simplest fix (although I haven't tested this cross browser yet) would be to alter the function isLocalStorageNameSupported() to test that you can also set some value.

https://github.com/marcuswestin/store.js/issues/42

function isLocalStorageNameSupported() 
{
    var testKey = 'test', storage = window.sessionStorage;
    try 
    {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return localStorageName in win && win[localStorageName];
    } 
    catch (error) 
    {
        return false;
    }
}
查看更多
登录 后发表回答