Web API - Client-side storage
브라우저 환경에서 데이터를 저장하는 방법을 시리즈 글로 소개하고 있습니다.
로컬 스토리지 localStorage 와 세션 스토리지 sessionStorage
로컬 스토리지 localStorage 와 세션 스토리지 sessionStorage 는 쿠키 Cookie 처럼 브라우저 내에서 Key/Value 로 데이터를 저장할 수 있는 저장소입니다. 로컬 스토리지와 세션 스토리지는 쿠키의 한계를 극복하기 위해 HTML5 와 함께 도입되었습니다.
쿠키는 오래동안 함께 했기에 익숙하고 사용하기 편리한 만큼 여러 한계를 가지는데 대표적인 한계로 서버가 허용하는 HTTP 헤더 크기 이상으로 쿠키에 데이터를 저장할 수 없다는 점입니다. HTTP 프로토콜 설계는 헤더의 크기를 제한하고 있지는 않지만, 많은 서버들이 HTTP 의 헤더 최대 크기를 제한하고 있습니다. 특히 쿠키는 클라이언트인 브라우저가 서버로 요청을 전송할 때마다 개발자의 의지와 상관없이 HTTP 헤더에 추가되어 전송되기 때문에 쿠키의 크기가 너무 커지면 서버에게 아무리 요청을 보내도 원하는 응답을 받을 수 없게 됩니다. 대체로 권장하는 쿠키의 최대 크기는 4KB 입니다. 또 다른 쿠키의 한계는 브라우저가 모든 요청에 쿠키를 포함해서 전송한다는 점입니다. 모든 요청에 동일한 데이터를 전송한다는건 매우 비효율적입니다.
이러한 쿠키의 한계를 극복하기 위해 등장한 Web API 가 Web Storage API 입니다. Web Storage API 는 크게 로컬 스토리지와 세션 스토리지로 구성되어 있습니다. 이 둘의 차이는 영구 쿠키와 세션 쿠키의 차이처럼 데이터의 생명주기로 구분됩니다. 로컬 스토리지는 브라우저가 종료되어도 저장된 데이터가 유지되는 반면, 세션 스토리지는 세션이 종료되면 데이터도 날아가게 됩니다. 쿠키는 처음 생성될 때부터 만료되는 순간을 설정하지만 로컬 스토리지의 경우 자바스크립트로 데이터를 삭제하거나 브라우저 설정에서 삭제하지 않는 이상 데이터는 사라지지 않습니다. 스토리지는 쿠키처럼 모든 요청마다 서버로 전송하지 않기 때문에 브라우저가 허용하는 한 저장 용량을 확보할 수 있습니다. 스토리지 최대 용량은 기기와 브라우저에 따라 다르고 복잡하게 계산되기 때문에 최대 어디까지 사용할 수 있다는 명확한 기준은 없습니다. 다만 저장소 크기를 테스트하는 사이트 에 따르면 대체로 5MB 크기 정도를 예상하고 사용할 수 있는 것 같습니다.
로컬 스토리지는 origin 을 기준으로 생성되고 공유됩니다. 즉 URL 의 scheme://host:port 가 동일하면 동일한 로컬 스토리지를 공유합니다. 따라서 같은 브라우저 내에서 탭이 달라도 같은 origin 이라면 동일한 로컬 스토리지가 공유됩니다.
반면 세션 스토리지는 브라우저의 탭과 운명을 함께 하기 때문에 탭 간에 데이터를 공유하는데 사용할 수 없습니다. 따라서 동일한 origin 이라도 다른탭이라면 다른 세션 스토리지를 생성하여 사용하게 됩니다. 다만 로컬 스토리지를 통해서 세션 스토리지를 탭 간에 공유하는 방법이 있는데, 특별한 상황이 아니라면 세션 스토리지를 탭에서 탭으로 옮기기 보다는 로컬 스토리지를 사용하는게 좋습니다.
아래와 같이 shcheme 이 HTTP 와 HTTPS 로 다르면 같은 호스트 (example.com) 와 포트 (80) 일지라도 Storage 는 별개로 관리됩니다.
http://example.com
https://example.com
로컬 스토리지와 세션 스토리지에 저장되는 데이터 타입은 UTF-16 DOMString 포맷으로 저장됩니다. 따라서 스토리지에 값으로 객체를 저장하려고 해도 스토리지 내부적으로 객체의 ToString
함수를 호출하여 자바스트립트 문자열 타입으로 전환해서 저장합니다. 따라서 스토리지에 저장된 데이터를 불러오면 스토리지에 전달했던 객체 타입이 아닌 문자열 타입이 돌아오니 사용할 때 주의해야 합니다. 예를 들어, null 을 저장하면 '' 이 아니라 'null' 이 저장되게 됩니다.
로컬 스토리지 localStorage
로컬 스토리지는 다음과 같이 전역 객체 window
를 통해서 사용할 수 있습니다.
window.localStorage.setItem('name', 'Yegun Kim');
// 전역 객체 window 는 생략 가능합니다.
localStorage.setItem('name', 'Yegun Kim');
localStorage.getItem('name');
세션 스토리지 sessionStorage
세션 스토리지는 다음과 같이 전역 객체 window
를 통해서 사용할 수 있습니다.
window.sessionStorage.setItem('name', 'Yegun Kim');
// 전역 객체 window 는 생략 가능합니다.
sessionStorage.setItem('name', 'Yegun Kim');
sessionStorage.getItem('name');
스토리지 인터페이스 Storage interface
세션 스토리지와 로컬 스토리지는 모두 스토리지 인터페이스 (Storage interface) 를 구현하기 때문에, 세션 스토리지와 로컬 스토리지 모두 데이터에 접근하고 수정하고 제거하는 방법이 동일합니다.
Storage.getItem()
으로 데이터를 가져올 수 있고, Storage.setItem()
으로 데이터를 저장할 수 있습니다. 더 자세한 인터페이스 명세는 MDN 글을 참고해주시길 바랍니다.
스토리지 이벤트 StorageEvent
스토리지에 데이터가 변경되었을 때 대응할 수 있도록 전역객체 window 에 이벤트가 있습니다. 다음과 같이 이벤트를 구독할 수 있습니다.
// 이벤트 리스너를 추가하는 방법
window.addEventListener('storage', () => { });
// 전역 객체 window 의 onstorage 를 설정하는 방법
window.onstorage = () => { };
이벤트 객체 속성에 대한 상세 스펙은 MDN 글 을 참고해주시길 바랍니다.
'Develop > Frontend 가이드' 카테고리의 다른 글
[FE] Web API - Client-side storage : Service Worker API & Cache (0) | 2021.05.28 |
---|---|
[FE] Web API - Client-side storage : IndexedDB (0) | 2021.05.12 |
[FE] Web API - Client-side storage : 쿠키 Cookie (0) | 2021.05.09 |
[FE] Typescript - Type Guard 타입 가드 (0) | 2021.05.05 |
[FE] HTTP/2 - HyperText Transfer Protocol (Version 2) 을 자세히 알아보자 (0) | 2021.04.13 |
꾸준히 노력하는 개발자 "김예건" 입니다.