자바스크립트로 웹 개발을 하다보면 데이터를 저장할 일이 생기는데, 보통 이럴 때 데이터베이스(DB) 서버나 클라우드(Cloud) 플랫폼, 세션, 쿠키 등에 데이터를 저장하는 경우가 많습니다.
저장해야할 데이터가 별로 중요하지 않거나, 유실되어도 무방하거나 테스트를 위한 데이터라면 디비 등을 이용하여 데이터를 저장하는 것이 낭비일 수 있습니다. 그래서 클라이언트 단, 즉 브라우저 상에 데이터를 저장할 수 있는 기술인 웹 스토리지에 대해서 알아보겠습니다.
로컬 스토리지 vs 세션 스토리지
웹 스토리지(web storage)에는 로컬 스토리지(localStorage)와 세션 스토리지(sessionStorage)가 있습니다. 이 두 개의 매커니즘의 차이점은 데이터가 어떤 범위 내에서 얼마나 오래 보존되느냐에 있습니다.
세션 스토리지는 웹페이지의 세션이 끝날 때 저장된 데이터가 지워지는 반면에, 로컬 스토리지는 웹페이지의 세션이 끝나더라도 데이터가 지워지지 않습니다.
세션 스토리지는 브라우저에서 같은 웹사이트를 여러 탭이나 창에 띄우면, 여러 개의 세션 스토리지에 데이터가 서로 격리되어 저장되며, 각 탭이나 창이 닫힐 때 저장해 둔 데이터도 함께 소멸되지만, 로컬 스토리지의 경우 여러 탭이나 창 간에 데이터가 서로 공유되며 탭이나 창을 닫아도 데이터는 브라우저에 그대로 남아 있습니다.
하지만 로컬 스토리지의 데이터 영속성(persistence)은 어디까지나 계속해서 동일 컴퓨터, 동일 브라우저를 사용할 때만 유지됩니다.
즉, 같은 컴퓨터에서 다른 브라우저를 사용하거나, 또는 다른 컴퓨터에서 같은 브라우저를 사용하는 경우에는 브라우저에 종속된 저장소이기 때문에 서로 공유가 되지 않습니다.
로컬 스토리지와 세션 스토리지는 두 기술 모두 데이터를 브라우저 상에 저장하고 자바스크립트에서 method의 형태가 동일합니다.
따라서 로컬 스토리지 기준으로만 설명을 하고 세션 스토리지를 사용하실 때는 아래 코드의 localStorage
부분을 sessionStorage
로 대체하면 동일하게 동작됩니다.
기본 메서드
웹 스토리지는 기본적으로 키(key)와 값(value)으로 이루어진 데이터를 저장할 수 있습니다.
자바스크립트에서의 웹 스토리지 기본적인 사용 방법은 다음과 같습니다.
// 키에 데이터 쓰기
localStorage.setItem("key", value);
// 키로 부터 데이터 읽기
localStorage.getItem("key");
// 키의 데이터 삭제
localStorage.removeItem("key");
// 모든 키의 데이터 삭제
localStorage.clear();
// 저장된 키/값 쌍의 개수
localStorage.length;
> localStorage.getItem('name')
null
> localStorage.getItem('email')
null
> localStorage.setItem('email', 'test@user.com')
undefined
> localStorage.getItem('email')
"test@user.com"
> localStorage.setItem('email', 'test@admin.com')
undefined
> localStorage.getItem('email')
"test@admin.com"
> localStorage.removeItem('email')
undefined
> localStorage.getItem('email')
null
주의 사항
*웹 스토리지는 오직 문자형(string) 데이터 타입만 지원한다는 사실을 항상 기억해야 합니다.
숫자형 데이터를 로컬 스토리지에 쓰고 다시 읽어오면 다음과 같이 숫자가 아닌 문자가 나오는 것을 알 수 있습니다.
> localStorage.setItem('num', 1)
undefined
> localStorage.getItem('num') === 1
false
> localStorage.getItem('num')
"1"
> typeof localStorage.getItem('num')
"string"
이러한 웹 스토리지의 성질 때문에 객체형 데이터를 저장할 때 다음과 같은 상황을 마주할 수 있습니다.
> localStorage.setItem('obj', {a: 1, b: 2})
undefined
> localStorage.getItem('obj')
"[object Object]"
이러한 문제가 발생하는 이유는 웹 스토리지는 문자열 데이터 밖에 저장할 수 없기 때문에, 다른 타입의 데이터를 저장하려고 할 때 문자형으로 변환을 하기 때문입니다.
> String(1)
"1"
> String({a: 1, b: 2})
"[object Object]"
해결 방법
웹 스토리지를 사용할 때 위와 같은 문제를 피하기 위해서 많이 사용하는 방법이 JSON 형태로 데이터를 만들고 stringify하여 쓰는 것입니다.
> localStorage.setItem('json', JSON.stringify({a: 1, b: 2}))
undefined
> JSON.parse(localStorage.getItem('json'))
{a: 1, b: 2}
위와 같이 로컬 스토리지에 쓸 데이터를 string 형태로 직렬화(serialization)하고, 읽은 데이터를 JSON 형태로 역직렬화(deserialization)해주면 원본의 데이터를 그대로 얻을 수 있습니다.
배열형 데이터를 로컬 스토리지에 저장할 때도 동일한 방법으로 사용하면 좋습니다.
> localStorage.setItem('nums', JSON.stringify([1, 2, 3]))
undefined
> JSON.parse(localStorage.getItem('nums'))
[1, 2, 3]
데이터 초기화
로컬 스토리지에 저장된 데이터는 웹페이지를 닫는다고 해서 사라지지 않으므로 불필요한 데이터가 남지 않도록 직접 초기화 해주는 것이 좋겠습니다.
> localStorage.length
5
> localStorage.key(0)
"email"
> localStorage.removeItem('obj')
undefined
> localStorage.length
4
> localStorage.clear()
undefined
> localStorage.length
0