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


219

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

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

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

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


2
일반적으로 사용 가능한 저장 공간을 초과 한 크기로 무언가를 저장하려고했음을 의미합니다. 어떤 브라우저 (Safari, Chrome 등)를 사용하고 있습니까? 사용하고있는 코드와 가능한 경우 저장하려는 데이터를 조금 더 공유 할 수 있습니까?

3
이것은 Safari 측의 버그 또는 문제로 간주되어야합니다. 그것은 당신이 ... 시크릿 모드에서 로컬 스토리지를 사용할 수 없다는 이해가되지 않습니다
막심 Luzik

이 특정 문제에 대한 테스트 기능을 사용하십시오 . 스토리지를 사용할 수없는 경우 memoryStorage로 localStorage를 감는 것을 고려 하십시오 . 면책 조항 : 나는 링크 된 패키지의 저자
스테인 드 위트

1
2017 년 4 월 패치가 Safari에 병합되어 다른 브라우저와 일치했습니다. Safari 11에 상륙 할 수 있습니다
sandstrom 1

2
이것이 Safari iOS 11에서 수정되었음을 확인할 수 있습니다. 테스트 된 개인 브라우징 + sessionStorage.setItem () 및 sessionStorage.getItem ()은 iPhone6 ​​및 iPhone8에서 성공적으로 수행되었습니다.
Kevin Gaudin

답변:


372

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

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

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


4
귀하의 게시물은 오늘 (24 시간 이내에) 저에게 매우 도움이되고시기 적절했습니다. 참고로, 개인 브라우징을 켜거나 끄는 방법은 다음과 같습니다. imore.com/how-use-private-browsing-ios-7-safari
Nick

12
+1 문제가 해결되었습니다. if( typeof Storage != 'undefined' ) { ... }정보를로드하고 저장하려고 시도하기 전에 LocalStorage ( ) 가 있는지 확인 했지만이 오류가 발생했습니다. 알고 보니 Storage여전히 사용할 때에도 정의된다. LocalStorage를 사용할 때마다 try / catch를 사용하십시오.
stevendesu

감사! 사파리에 의한 이상한 오류. 보다 유익한 정보 였을 것입니다. : D
Sunny R Gupta

2
Safari Tech Preview 29에서 "개인 브라우징 모드 또는 WebDriver 세션에서 localStorage에 저장할 때 수정 된 QuotaExceededError"가 수정 될 수 있습니다. 참조 developer.apple.com/safari/technology-preview/release-notes
마크 Baumbach

1
예를 들어 이미지를 저장하여 쉽게 수행 할 수있는 저장 제한에 도달 한 경우에도 발생할 수 있습니다.
csalmeida

103

다른 답변에서 언급했듯이 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.');
    }
}

1
어쨌든 setItem을 사용할 수없는 경우 setItem을 Storage 객체에 추가해야합니까?
네크로맨서

4
내 스 니펫의 요점은 Safari 개인 모드에서 앱이 완전히 중단되지 않도록하려는 경우 JS 오류가 발생하지 않도록 단순히 무시하는 것입니다.
philfreo 2016 년

16

나는이 간단한 함수, 반환 사용 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')
}

내가 놓친 것이 있습니까? 라는 메소드 window.sessionStorage대신 왜 사용 됩니까? window.localStorageisLocalStorageNameSupported
Ithar

@lthar-여기에서 설명서를 참조하십시오 : w3schools.com/html/html5_webstorage.asp 가장 중요한 부분 :HTML local storage provides two objects for storing data on the client: window.localStorage - stores data with no expiration date window.sessionStorage - stores data for one session (data is lost when the browser tab is closed)
DrewT

@DrewT, 그러나 테스트 키를 제거하면이 상황의 차이점은 무엇입니까? 테스트 키를 삭제하려는 경우 테스트 키를 저장할 위치는 중요하지 않습니다. 내가 잘못? 세션 스토리지가 로컬 스토리지보다 나은 이유는 무엇입니까?
Vladyslav Turak

1
@TurakVladyslav 당신이 옳다는 것은 sessionStorage당신이 개발을 테스트하고 싶을 때 중단 점을 설정하는 데보다 관리하기 쉽다는 것을 제외하고는 여기에 실제로 차이가 없습니다 . "더 나은"이라는 주장은 없으며, 실제로주의를 기울이는 것은 개인적인 취향 일뿐입니다. 참고로 중요한 것은 둘 것입니다 sessionStoragelocalStorage에서 HTML5 webstorage API를 모두 구현합니다.
DrewT


3

다음은 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' );
...

2

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

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

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

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


정확히 무엇을 수정합니까? 아무것도 지속되지 않으므로 요점은 무엇입니까?
Esben Skov Pedersen

1
개인 브라우징 모드에서 Safari를 "고정"합니다. (이 답변은 명확하지 않습니다. 지적 해 주셔서 감사합니다. 답변을 편집하겠습니다.) 비공개 브라우징 모드에 관계없이 아무것도 유지되지 않으므로 지속되지 않는 것은 관련이 없습니다. 이 문제는 Safari에서 개인 브라우징 모드에 있어도 사용자가 기존의 응용 프로그램을 주요 재 작성없이 실행할 수 있도록하는 것이 었습니다.
Josef Engelfrost

2

업데이트 (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 등에서 더 많은 테스트를 수행해야합니다. 실제로 문제가 해결되는지 확인하십시오.


편집자 John : 귀하와 Jonathan Alzetta가 동일한 계정 일 가능성이 높다는 것을 알고 있으며 귀하는 답변을 개선하려고 노력하고 있습니다. 그러나 Jonathan Alzetta로 로그인하여이 답변을 편집해야합니다. 검토 대기열 필요한 경우 계정을 복구하십시오.
DavidS


0

이 질문과 답변을 통해 Parse에서 신규 사용자를 등록 할 때 발생하는 특정 문제를 해결할 수있었습니다.

signUp (attrs, options) 함수는 로컬 저장소를 사용하여 세션을 유지하기 때문에 사용자가 개인 탐색 모드 인 경우 "QuotaExceededError : DOM 예외 22 : 할당량을 초과 한 저장소에 무언가를 추가하려고했습니다." 예외 및 성공 / 오류 함수는 호출되지 않습니다.

필자의 경우 오류 함수가 호출되지 않았기 때문에 처음에는 제출시 클릭 이벤트를 발생시키는 문제 또는 가입 성공에 정의 된 리디렉션이 문제인 것처럼 보입니다.

사용자에게 경고를 포함하면 문제가 해결되었습니다.

자바 스크립트 SDK 구문 분석 https://parse.com/docs/js/api/classes/Parse.User.html#methods_signUp

사용자 이름 (또는 이메일)과 비밀번호로 새로운 사용자를 등록합니다. 그러면 서버에 새로운 Parse.User가 생성 되고 {@link #current}를 사용하여 사용자에게 액세스 할 수 있도록 localStorage의 세션이 유지됩니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.