...
LocalStorage / SessionStorage API 소개
html5에서는 좀 더 쉽고 간단한 저장소 제공을 위해 새로운 localStorage와 sessionStorage API를 제공한다.
둘 다 저장 공간으로 사용할 수 있는데 이 둘의 가장 큰 차이점이라면 저장소로서의 기능은 대부분 동일하며 단지 sessionStorage의 경우 세션이 종료되면 저장된 데이터도 함께 사라진 다는 점이 다른 점이다.
[ localStorage ]
- 로컬에 도메인 별로 지속되는 storage
- localStorage는 시간제한이 없고 브라우저가 꺼져도 죽지 않는다.
- 값을 지우려면 직접 지워줘야한다. (나는 지우기 직전까지 죽지않아)
[ sessionStorage ]
- 세션이(프로세스, 탭, 브라우저) 종료될 때까지 지속되는 storage
- 세션 스토리지는 localStorage와 쓰는 느낌이 비슷한데 커다란 차이점이 있다. 그것은 바로 소멸 타이밍이다.
- localStorage는 소멸타이밍이 없다. 즉 직접 지워줘야한다. 그러나 sessionStorage는 세션의 종료시 죽음을 맞이한다. (난 세션이 끊기면 죽는다)
그런데 이 session이라는 용어는 아주 우리가 일반적인 의미의 세션과는 좀 다르다.
보통 세션의 종료는 일반적으로 브라우저의 종료를 뜻한다.
새창을(프로세스)띄우건 새탭을 띄우건 이는 세션종료를 의미하지 않는다.
그러나 sessionStorage에서 의미하는 세션은 가장 작은 단위인 탭단위를 의미한다.
탭마다 sessionStorage는 따로 배정되며 서로의 영역을 공유하지 않는다. 따라서 값을 침범할 수 도 없다.
그래서 sessionStorage는 더 각별하다.
cookie가 가졌던 근본적인 문제인 도메인 같으면 항상 쿠키를 보낸다는 조건이 sessionStorage를 통해 해소하려한 흔적이 보인다.
크롬 개발자 도구에서 webStorage 보기
개발자 도구 상단 메뉴에 Application 창에 들어가면 쿠키 정보와 함께 스토리지 정보를 확인 할 수 있다.
쿠키(Cookie) vs 로컬 스토리지 비교
로컬 저장소를 웹에서 사용할 경우 가장 많이 사용되는 방법은 쿠키 그리고 로컬스토리지 다.
이때 쿠키(Cookie)와 로컬스토리지(Local Storage)은 둘 다 다른 목적을 가지고 있기 때문에 무엇이 옳다고 하기는 애매한 부분이 있다. 각각의 쓰임새에 따라 적합한 방법을 선택해야 한다.
우선 쿠키는 서버측과 클라이언트측 양쪽에서 쿠키 데이터를 사용하는 api가 존재한다.
이와 달리 localStorage는 로컬 환경에서만 컨트롤된다.
이런 이유로 저장된 쿠키 데이터의 쓰임이 양쪽 모두이냐를 고려해야하며 만약 서버쪽 사용이 필수적이고 잦다면 로컬 저장소가 아닌 클라이언트와 서버와의 인터렉션이 좀 더 효과적인 쿠키값을 사용하는 것이 좋을 수도 있다.
그리고 우리가 어떤 웹사이트에 들어가면 항상 보는 광고 7일 동안 보지 않기 역시 쿠키 기능이다.
왜냐하면 로컬 스토리지에는 기간 기능이 없기 때문이다.
그렇지만 클라이언트에 데이터를 저장한다는 점으로서는 로컬스토리지는 매우 매력적인 기능이다.
로컬 스토리지의 우위성
쿠키와 달리 로컬(웹)스토리지는 자바스크립트 객체 자체를 넣는것 역시 가능하며 문자열에 크기제한이 있는 cookie에 비해서 비교우위를 가진다.
그리고 세션을 이용시에, request와 response시에 모든 쿠키를 다 넘겨야 했는데 원래 비용이 큰 http통신에 더 큰 부하를 준다.
그러나 WebStorage는 그냥 개발자가 선별해서 넘기면 되므로 http통신에도 부하를 줄일 수 있다.
브라우저가 종료되면 자동으로 사라지는 쿠키를 재현하기 위해서 sessionStorage를 도입하였다.
sessionStorage의 존재로 세션이 유지되는 동안만 필요한 데이터를 저장할 수 있게 되었다.
또한 쿠키는 domain별로 데이터가 분리되지만 같은 브라우저라면 값을 공유했다.
sessionStorage는 다른 탭이라면 데이터가 공유도지 않는다.
만약 공유할 데이터는 localStorage에 넣으면 되므로 선택의 폭이 커졌다.
쿠키는 자신의 변화를 감지할 방법이 없다.
web storage는 자신의 변화를 이벤트로 감지할 수 있다.
1. 제한
cookie - 용량제한, 시간제한, 갯수제한 존재
webstorage - 용량제한만 존재
2. 시간제한 설정
cookie - 시간제한 설정가능
webstorage - 시간제한 설정 불가능
3. 데이터형
cookie - 문자열만 저장가능
webstorage - javascript 객체 저장가능
4. 데이터 전송
cookie - 모든 쿠키를 전송해야함, cookie를 가공함으로써 발생하는 side effect존재
webstorage - 개발자가 선택해서 전송할 수 있고 가공할 수도 있음
5. 세션의 정의
cookie - 같은 브라우저면 다른 탭이나 다른 창(프로세스)일지라도 같은 세션이라고 정의
webstorage - 같은 브라우저일지라도 sessionStorage의 경우 다른 탭이면 다른 세션이라고 정의
6. 이벤트
cookie - 이벤트 없음
webstroage - 이벤트 존재
LocalStorage / SessionStorage 사용법
LocalStorage 사용법
앞에도 언급했지만 위 두가지 객체의 차이점은 세션에 따라서 데이터가 유지되는가 안되는가로 구분할 수 있다.
그렇기 때문에 사용하는 방법도 거의 동일하다 하겠다.
아래는 localStorage객체의 사용로 자주 사용되는 메소드, 프로퍼티를 함께 알아보자.
데이터의 저장
특정값의 데이터를 저장하기 위한 방법으로 아래와 같이 메소드를 사용하거나
리터럴하게 사용하는 두 가지 방법이 가능하다.
아래 예제는 test란 이름의 key값을 정하고 이에 123이란 값을 저장하는 예제이다.
localStorage.test = '123'; // 리터럴 방식
localStorage.setItem('test', '123'); // 메소드 방식
데이터 불러오기
localStorage.test; // 리터럴 방식
localStorage.getItem('test'); // 메소드 방식
localStorage.getItem(); // 인자를 안주면, 전체 값 받아오기
localStorage.length // 항목 갯수 반환
localStorage.key(0); // 인자(인덱스)에 해당하는 key의 value값을 받아온다.
데이터 삭제
localStorage.removeItem('test');
// localStorage 객체에서 원하는 값을 지우는 방법
localStorage.clear();
// 한번에 저장된 모든 값을 삭제하는 방법
키 순회하기
아쉽게도 스토리지 객체는 iterable 객체가 아니다.
대신 배열처럼 다루면 전체 키-값을 얻을 수 있다.
let keys = Object.keys(localStorage);
for(let key of keys) {
alert(`${key}: ${localStorage.getItem(key)}`);
}
value값을 객체로 이용하기
localStorage의 키와 값은 반드시 문자열이어야 한다.
숫자나 객체 등 다른 자료형을 사용하게 되면 문자열로 자동 변환된다.
localStorage.user = {name: "John"};
alert(localStorage.user); // [object Object]
JSON을 사용하면 배열과 객체를 저장할수 있다.
localStorage.user = JSON.stringify({name: "John"});
let user = JSON.parse( localStorage.user );
alert( user.name ); // John
let arr = [1,2,3,4,5]
localStorage.setItem("data", JSON.stringify(arr));
let output = localStorage.getItem("data");
let arr = JSON.parse(output);
console.log(arr) // [1,2,3,4,5]
디버깅 등의 목적으로 스토리지 객체 전체를 문자열로 변환하는 것도 가능하다.
alert( JSON.stringify(localStorage, null, 2) );
sessionStorage 사용법
세션을 기준으로 데이터가 저장 및 유지되기 때문에 이 객체에 저장된 값은 일시적인 수명을 가지게된다.
만약 세션이 종료되는 경우... 브라우저를 닫거나 일정시간 아무런 동작도 하지 않는다면 당연히 저장된 값은 삭제될 것이다.
기본적인 문법은 로컬스토리지와 크게 차이가 없다.
sessionStorage.setItem("domain", "webisfree.com");
// domain이란 키(key) 값을 사용하여 해당 텍스트를 저장함
sessionStorage.getItem("domain");
// 키에 저장된 값을 반환. 여기서는 webisfree.com 출력됨
sessionStorage.removeItem("domain");
// domain 키와 데이터 모두 삭제
sessionStorage.clear();
// 저장된 모든 값 삭제
Storage EVENT
localStorage나 sessionStorage의 데이터가 갱신될 때, storage 이벤트가 실행된다.
storage 이벤트는 다음과 같은 프로퍼티를 지원한다.
- key – 변경된 데이터의 키(.clear()를 호출했다면 null)
- oldValue – 이전 값(키가 새롭게 추가되었다면 null)
- newValue – 새로운 값(키가 삭제되었다면 null)
- url – 갱신이 일어난 문서의 url
- storageArea – 갱신이 일어난 localStorage나 sessionStorage 객체
여기서 중요한 점은 storage 이벤트가 이벤트를 발생시킨 스토리지를 제외하고 스토리지에서 접근 가능한 window 객체 전부에서 일어난다는 사실이다.
두 개의 창에 같은 사이트를 띄워놨다고 가정해보자.
창은 다르지만 사이트가 같기 때문에 localStorage는 서로 공유된다.
두 창에서 모두 storage 이벤트를 수신하고 있기 때문에 한 창에서 아래 예시를 실행해 데이터를 갱신하면 다른 창에 해당 사항이 반영되는 것을 확인할 수 있을 것이다.
// 문서는 다르지만, 갱신은 같은 스토리지에 반영됩니다.
window.onstorage = event => { // window.addEventListener('storage', () => {와 같습니다.
if (event.key != 'now') return;
alert(event.key + ':' + event.newValue + " at " + event.url);
};
localStorage.setItem('now', Date.now()); // 데이터를 갱신하면 storage 이벤트가 발생
storage 이벤트의 또 다른 중요한 특징은 event.url이 있어 데이터가 갱신된 문서의 URL을 알 수 있다는 점이다.
또한 event.storageArea에는 스토리지 객체가 포함되어 있는데,
storage 이벤트는 sessionStorage나 localStorage가 변경될 때 모두 발생하기 때문에 event.storageArea는 스토리지 종류에 상관없이 실제 수정이 일어난 것을 참조한다는 것 역시 중요한 특징이다.
변경이 일어났을 때 우리는 event.storageArea에 무언가를 설정해 '응답’이 가능하도록 할 수 있다.
메세지 교환
이런 특징을 이용하면 오리진이 같은 창끼리 메시지를 교환하게 할 수 있다.
모던 브라우저는 오리진이 같은 창끼리 통신할 수 있도록 해주는 브로드캐스트 채널 API(broadcast channel API)를 지원한다.
그런데 이 API는 기능은 풍부하지만, IE에서는 지원하지 않는다는 단점이 있다. (그놈의 IE ...)
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.