-
[Web] Web Storage에 대하여programing/Web 2020. 12. 26. 21:46
Web Storage API
개념
HTML에 정의된 명세인 Web Storage API는 Storage API에 속한 개념이며, 브라우저에서 키/값 쌍을 쿠키보다 훨씬 직관적으로 저장할 수 있는 방법을 제공합니다.
키와 값은 모두 String 형입니다.
window.sessionStorage
및window.localStorage
는 Storage 인스턴스이며, 이 인스턴스를 통해 Web Storage API를 사용할 수 있습니다.이 Storage 인스턴스는 일반적인 객체처럼 다룰 수 있지만, pitfall 관련 이슈를 방지하기 위해서 제공되는 메소드를 통해 다루는 것을 권장합니다.
제공하는 속성
Web Storage API는
window
에 다음과 같은 속성을 제공합니다.- sessionStorage : 세션 스토리지 인스턴스입니다.
- localStorage : 로컬 스토리지 인스턴스입니다.
- onstorage : 다른 문서에서 현재 세션의 스토리지가 변경되었을 때 이벤트를 발생시킵니다. 해당 이벤트의 파라미터인
e
는 다음과 같은 속성을 가집니다.- key
- newValue
- oldValue
- storageArea
- url
다음은 로컬 스토리지 이벤트 테스트 예제입니다.
물론,
addEventListener
를 이용해서 이벤트 핸들러를 할당할 수 있습니다.window.addEventListener('storage', function(e) { ... });
API 지원 검사
MDN에서 제공하는 검사 함수는 다음과 같습니다.
function storageAvailable(type) { var storage; try { storage = window[type]; var x = '__storage_test__'; storage.setItem(x, x); storage.removeItem(x); return true; } catch(e) { return e instanceof DOMException && ( // Firefox를 제외한 모든 브라우저 e.code === 22 || // Firefox e.code === 1014 || // 코드가 존재하지 않을 수도 있기 떄문에 이름 필드도 확인합니다. // Firefox를 제외한 모든 브라우저 e.name === 'QuotaExceededError' || // Firefox e.name === 'NS_ERROR_DOM_QUOTA_REACHED') && // 이미 저장된 것이있는 경우에만 QuotaExceededError를 확인하십시오. (storage && storage.length !== 0); } }
if (storageAvailable('localStorage')) { // 야호! 우리는 localStorage를 사용할 수 있습니다. }
사생활 보호 및 시크릿 모드
사생활 보호 기능을 켠 대부분의 브라우저는 탐색 기록 및 쿠키 등을 남기지 않기 때문에, Web Storage API를 제대로 사용할 수 없습니다. 브라우저 마다 API를 처리하는 방식이 다르니 주의해야 합니다.
Web Storage
Web Storage 조회하기
Chrome 기준으로, 개발자 도구 -> 어플리케이션 -> 스토리지 에서 스토리지에 저장된 데이터들을 조회할 수 있습니다.
Box Mode
각 site storage unit에 포함된 실제 데이터 저장공간을 box라고 하며, 하나의 site storage unit은 하나의 box만을 가집니다.
이 box를 관리하는 방법을 box mode라고 하는데, 크게 두가지 종류로 나눌 수 있습니다.
- Best Effort : 유저를 방해하지 않으면서 브라우저에 의해 정리될 수 있습니다. (약간 가비지 콜렉터 느낌) 따라서 지속성이 짧습니다.
- Persistent (Permission) : 스토리지 용량이 적어도 자동으로 정리되지 않습니다. 유저가 브라우저 세팅 등을 통해 직접 정리해야 합니다.
기본적으로 브라우저는 IndexedDB와 Cache Storage를 포함한 사이트 데이터를 Best Effort로 관리한다고 합니다.
persist 유무는 다음과 같이 확인할 수 있습니다.
navigator.storage.persisted().then(isPersiste => console.log(isPersist));
Box Mode를 persist로 바꾸고 싶다면, 다음과 같이 요청할 수 있습니다.
navigator.storage.persist().then(...).catch(...);
Web Storage 종류
Session Storage
특성
세션 스토리지는 각 출처에 대해 독립적인 저장 공간을 페이지 세션(탭)이 유지되는 동안 제공합니다.
- 기본적으로 스토리지는 해당 출처에 묶이므로, 다른 스토리지에 접근할 수 없습니다.
- 새로운 페이지 세션이 생성되면 세션 스토리지를 생성하며, 페이지 세션이 유지되는 동안 데이터를 유지합니다. 새로고침 및 탭 복구를 포함해서, 브라우저가 열려 있는 한 최대한 긴 시간동안 유지됩니다.
- 해당 페이지 세션에 귀속되므로, 웹 워커나 서비스 워커에서 접근할 수 없습니다.
- 출처 별로 독립된 스토리지을 사용합니다. 같은 출처(혹은 URL)라도, 탭이 다르다면 별개의 세션 스토리지를 사용합니다.
- 저장된 데이터를 서버로 절대 보내지 않습니다. (local storage도 동일할 것으로 추측되지만, MDN에서는 별도로 표기를 해놓지 않았네요.)
- 저장공간이 쿠키보다 큽니다. (최대 5MB)
- 동기적이므로, 메인 스레드를 블로킹 할 수 있습니다.
활용
- indexedDB의 키를 저장
- Form의 데이터를 저장 (만약 탭이 죽어버린 경우, 탭 복구를 하면 필드 값들을 복원. 아마 onBlur에서 저장하면 되지 않을까.. 싶음)
Local Storage
특성
로컬 스토리지는 세션 스토리지와 동일하지만, 세션을 닫아도 저장 공간이 유지됩니다.
- 기본적으로 스토리지는 해당 출처에 묶이므로, 다른 스토리지에 접근할 수 없습니다.
- 세션 유지 유무와 상관 없이, 반영구적으로 데이터를 유지합니다.
- 출처 별로 독립된 저장 공간을 제공합니다. 같은 출처라면, 탭이 다르더라도 동일한 스토리지를 사용합니다. (위 예제에서 두 탭은 동일한 출처라서, 동일한 로컬 스토리지를 공유합니다.)
- 브라우저 캐시 혹은 로컬 저장 데이터를 지우면 데이터가 파기됩니다.
- 저장공간이 세션 스토리지보다 큽니다. (정확히 몇 MB가 가능한지 모르겠네요.)
- 동기적이므로, 메인 스레드를 블로킹 할 수 있습니다.
활용
- 티케팅 사이트에서 여러 탭으로 동시 구매를 막는 용도..? (물론 서버 측 대응도 필요하겠지만)
- n일 동안 보지 않기
- 자동 로그인 설정
Indexed DB
클라이언트 측에 file 및 blob을 포함한 구조화된 데이터를 저장하기 위한 low-level API입니다.
웹 스토리지에 비해, 큰 데이터를 저장하는데 적합합니다.
비동기적으로 동작합니다.
Indexed DB는 Web Storage API에 포함되지 않습니다.
Cache Storage API
HTTP 요청 및 응답을 저장하기 위한 Cache 객체를 저장하기 위한 저장소입니다.
비동기적으로 동작합니다.
CacheStorage API 또한 Web Storage API에 포함되지 않습니다.
쿠키와 웹 스토리지
쿠키는 모든 HTTP 요청에 자동으로 데이터가 포함됩니다. 그러나 웹 스토리지는 요청에 절대 데이터를 포함하지 않습니다.
쿠키와 다르게, HTTP 헤더를 통해 스토리지를 변경할 수 없습니다. 오로지 JS로만 조작할 수 있습니다.
쿠키가 웹 스토리지보다 더 안전하다고 하네요. (HttpOnly 및 Secure 설정이 가능하니까. 그래도 본질적으로 안전하지는 않다고 합니다.)
기타
대부분의 브라우저의 쿠키의 저장 용량은 약 4KB라고 합니다. (쿠키 개수는 약 150 ~ 180개)
크롬은 디스크 크기의 80%를 휴리스틱 풀로 계산한다고 합니다.
참고
https://web.dev/storage-for-the-web/
https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API
https://web.dev/persistent-storage/
https://docs.google.com/document/d/19QemRTdIxYaJ4gkHYf2WWBNPbpuZQDNMpUVf8dQxj4U/preview
'programing > Web' 카테고리의 다른 글
[CSS] column-count를 이용하여 masonry layout 구현하기 (2) 2021.02.28 [React] Styled-Components를 이용한 애니메이션 (0) 2021.01.30 [Web] JSON Web Token (0) 2020.12.03 [WEB] CORS에 대한 정리 (0) 2020.07.22 [React, Redux] 내가 리덕스를 쓰지 않는 이유 (0) 2020.07.18 댓글