[javascript] QuotaExceededError : Dom exception 22 : 할당량을 초과 한 스토리지에 무언가를 추가하려고했습니다.

iOS 7이 설치된 iPhone에서 LocalStorage를 사용하면이 오류가 발생합니다. 나는 해결책을 찾고 있었지만 비공개로 탐색조차하지 않는다는 것을 고려하면 아무런 관련이 없습니다.

iOS 7에서 localStorage가 기본적으로 비활성화되는 이유를 이해하지 못합니까? 다른 웹 사이트에서도 테스트했지만 운이 없습니다. http://arty.name/localstorage.html 이 웹 사이트를 사용하여 테스트를 시도했지만 이상한 이유로 전혀 아무것도 저장하지 않는 것 같습니다.

누구든지 같은 문제가 있었지만 운 좋게 고쳤습니다. 저장 방법을 전환해야합니까?

나는 몇 줄의 정보 만 저장하여 열심히 논쟁했지만 아무 소용이 없습니다. 표준 localStorage.setItem()기능을 사용하여 저장했습니다.



답변

Safari가 개인 모드 탐색 중일 때 발생할 수 있습니다. 비공개 브라우징 중에는 로컬 저장소를 전혀 사용할 수 없습니다.

한 가지 해결책은 앱이 작동하기 위해 비 개인 모드가 필요하다는 것을 사용자에게 경고하는 것입니다.

업데이트 : 이것은 Safari 11 에서 수정 되었으므로 이제 다른 브라우저와 동작이 정렬되었습니다.


답변

다른 답변에서 언급했듯이 localStorage.setItem(또는 sessionStorage.setItem)가 호출 되면 iOS 및 OS X의 Safari 개인 브라우저 모드에서 항상 QuotaExceededError 가 발생합니다.

한 가지 해결책 은를 사용하는 각 인스턴스에서 try / catch 또는 Modernizr 검사 를 수행하는 것 setItem입니다.

그러나이 오류가 전체적으로 중단되는 shim을 원한다면 나머지 JavaScript가 중단되는 것을 방지하기 위해 다음을 사용할 수 있습니다.

https://gist.github.com/philfreo/68ea3cd980d72383c951

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


답변

나는이 간단한 함수, 반환 사용 true또는 false로컬 스토리지의 적용 여부에 대한 테스트 :

isLocalStorageNameSupported = function() {
    var testKey = 'test', storage = window.sessionStorage;
    try {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return true;
    } catch (error) {
        return false;
    }
}

이제 localStorage.setItem()사용하기 전에 가용성을 테스트 할 수 있습니다 . 예:

if ( isLocalStorageNameSupported() ) {
    // can use localStorage.setItem('item','value')
} else {
    // can't use localStorage.setItem('item','value')
}


답변

iOS 7에서 동일한 문제로 실행되었습니다 (일부 장치에서는 시뮬레이터가 없음).

iOS 7의 Safari는 저장 용량이 낮으며 기록 기록이 길면 도달 할 수 있습니다.

최선의 방법은 예외를 잡는 것입니다.

Modernizr 프로젝트에는 쉬운 패치가 있습니다. https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js


답변

다음은 localStorage를 사용할 수없는 경우 쿠키를 사용하는 DrewT의 답변을 기반으로 한 확장 솔루션입니다. Mozilla의 docCookies 라이브러리를 사용 합니다 .

function localStorageGet( pKey ) {
    if( localStorageSupported() ) {
        return localStorage[pKey];
    } else {
        return docCookies.getItem( 'localstorage.'+pKey );
    }
}

function localStorageSet( pKey, pValue ) {
    if( localStorageSupported() ) {
        localStorage[pKey] = pValue;
    } else {
        docCookies.setItem( 'localstorage.'+pKey, pValue );
    }
}

// global to cache value
var gStorageSupported = undefined;
function localStorageSupported() {
    var testKey = 'test', storage = window.sessionStorage;
    if( gStorageSupported === undefined ) {
        try {
            storage.setItem(testKey, '1');
            storage.removeItem(testKey);
            gStorageSupported = true;
        } catch (error) {
            gStorageSupported = false;
        }
    }
    return gStorageSupported;
}

소스에서 다음을 사용하십시오.

localStorageSet( 'foobar', 'yes' );
...
var foo = localStorageGet( 'foobar' );
...


답변

다른 답변에서 이미 설명했듯이 개인 정보 보호 모드에있을 때 Safari는로 데이터를 저장하려고 할 때 항상 이 예외를 발생 localStorage.setItem()시킵니다.

이 문제를 해결하기 위해 메서드와 이벤트 모두 localStorage를 모방하는 가짜 localStorage를 작성했습니다.

가짜 로컬 저장소 : https://gist.github.com/engelfrost/fd707819658f72b42f55

이것은 아마도 문제에 대한 일반적인 해결책이 아닐 수도 있습니다. 이것은 대안이 이미 존재하는 응용 프로그램에 대한 주요 재 작성이 될 시나리오에 대한 좋은 솔루션이었습니다.


답변

업데이트 (2016-11-01)

이 문제를 해결하기 위해 아래 언급 된 AmplifyJS를 사용하고있었습니다. 그러나 비공개 브라우징에서 Safari의 경우 메모리 기반 스토리지로 다시 넘어갔습니다. 제 경우에는 사용자가 여전히 비공개 브라우징을하고 있어도 새로 고칠 때 저장소가 지워졌 기 때문에 적절하지 않습니다.

또한 iOS Safari에서 항상 개인 모드로 탐색하는 많은 사용자를 발견했습니다. 이러한 이유로 Safari의 더 나은 대안은 쿠키 (사용 가능한 경우)를 사용하는 것입니다. 기본적으로 쿠키는 비공개 브라우징에서도 액세스 할 수 있습니다. 물론 개인 브라우징을 종료 할 때 지워지지 만 새로 고침시 지워지지는 않습니다.

로컬 스토리지 폴백 라이브러리를 찾았습니다 . 설명서에서 :

목적

“비공개 브라우징”과 같은 브라우저 설정을 사용하면 최신 브라우저에서도 작업중인 window.localStorage에 의존하는 것이 문제가되었습니다. 존재하더라도 setItem 또는 getItem을 사용하려고하면 예외가 발생합니다. 이 모듈은 적절한 검사를 실행하여 사용 가능한 브라우저 저장 메커니즘을 확인한 후 노출합니다. localStorage와 동일한 API를 사용하므로 대부분의 경우 드롭 인 대체로 작동해야합니다.

문제를 조심하십시오 :

  • CookieStorage에는 스토리지 제한이 있습니다. 여기서 조심하십시오.
  • 메모리 저장소는 페이지로드간에 지속되지 않습니다. 이것은 페이지 충돌을 막기위한 스톱 갭이지만, 전체 페이지로드를 수행하지 않는 웹 사이트에는 충분할 수 있습니다.

TL; DR :

사용 로컬 스토리지 대체 (와 통합 API .getItem(prop).setItem(prop, val))

브라우저에 적합한 스토리지 어댑터 (localStorage, sessionStorage, 쿠키, 메모리)를 확인하고 사용하십시오.

원래 답변

이전 답변을 추가하려면 가능한 한 가지 해결 방법은 저장 방법을 변경하는 것입니다. AmplifyJSPersistJS 와 같은 몇 가지 라이브러리 가 있습니다. 두 라이브러리 모두 여러 백엔드를 통해 지속적인 클라이언트 측 스토리지를 허용합니다.

증폭 JS

localStorage

  • IE 8 이상
  • Firefox 3.5 이상
  • 사파리 4+
  • 크롬
  • 오페라 10.5+
  • 아이폰 2 이상
  • 안드로이드 2 이상

sessionStorage

  • IE 8 이상
  • Firefox 2 이상
  • 사파리 4+
  • 크롬
  • 오페라 10.5+
  • 아이폰 2 이상
  • 안드로이드 2 이상

globalStorage

  • Firefox 2 이상

사용자 데이터

  • IE 5-7
  • userData는 최신 버전의 IE에도 존재하지만 IE 9 구현의 단점으로 인해 localStorage가 지원되는 경우 userData를 등록하지 않습니다.

기억

  • 사용 가능한 다른 스토리지 유형이없는 경우 인 메모리 저장소가 대체로 제공됩니다.

PersistentJS의 경우

  • 플래시 : 플래시 8 영구 저장소.
  • 기어 : Google Gears 기반 영구 저장소.
  • localstorage : HTML5 초안 저장소.
  • globalstorage : HTML5 초안 저장 (이전 사양).
  • 즉, Internet Explorer 사용자 데이터 동작.
  • 쿠키 : 쿠키 기반 영구 저장소.

스토리지 계층 선택에 대해 걱정할 필요가없는 추상화 계층을 제공합니다. 스토리지 유형에 따라 일부 제한 (예 : 크기 제한)이있을 수 있습니다. 지금은 AmplifyJS를 사용하고 있지만 iOS 7 / Safari 등에서 더 많은 테스트를 수행해야합니다. 실제로 문제가 해결되는지 확인하십시오.