
업무 진행 중 기존 DB 기반 데이터 저장 외에도 클라이언트 측 임시 데이터 저장 기능이 필요하다는 의견을 전달받았다.
그래서 로컬 스토리지를 함께 사용하는 구조로 개선하는 작업을 진행하게 되었다.
마침 좋은 기회라 생각하고, 웹 스토리지를 개념, 조작법, 쓰기 좋은 상황 순서로 간략하게 정리해보려고 한다.
웹 스토리지란?
웹 스토리지는 클라이언트 측에 데이터를 key-value 형식으로 저장할 수 있도록 도입된 API이다.
간단한 특징으로는 다음과 같다.
- 값은 반드시 문자열(String)로 저장된다.
- 서버로 자동 전송되지 않는다. (반면, 쿠키는 서버로 자동 전송된다.)
- 용량은 일반적으로 5MB ~
또한, 웹 스토리지는 데이터의 지속성에 따라 두가지로 나뉘어진다.
바로 영구 저장소인 로컬 스토리지(Local Storage)와 임시저장소 세션 스토리지(Session Storage)이다.
로컬 스토리지 (Local Storage)
페이지를 닫거나 브라우저를 종료해도 영구적으로 남는 클라이언트 저장소다.
주요 특징은 다음과 같다.
- 명시적으로 removeItem() 또는 clear()를 사용하지 않는 이상 만료되지 않는다.
- 동일 도메인 내에서만 접근이 가능하다.
주요 메서드는 다음과 같다.
localStorage.setItem('key', 'value'); // 저장
localStorage.getItem('key'); // 조회
localStorage.removeItem('key'); // 제거
localStorage.clear(); // 전체 삭제
localStorage.length; // 저장된 항목 개수
localStorage.key(index); // index로 key 조회
세션 스토리지 (Session Storage)
브라우저 탭 단위로 유지되는 클라이언트 저장소다.
주요 특징은 다음과 같다.
- 탭을 닫는 즉시 데이터가 소멸된다.
- 같은 브라우저, 같은 도메인이라도 탭이 다르면 공유되지 않는다.
주요 메서드는 다음과 같다. (Local Storage 와 동일하다)
sessionStorage.setItem('key', 'value'); // 저장
sessionStorage.getItem('key'); // 조회
sessionStorage.removeItem('key'); // 제거
sessionStorage.clear(); // 전체 삭제
sessionStorage.length; // 저장된 항목 개수
sessionStorage.key(index) // index로 key 조회
스토리지 조작하기
순회
웹 스토리지 객체는 iterable 객체는 아니다. (유사 배열 객체일 뿐) for...of, forEach 등으로 직접 순회가 가능하진 않다.
그렇기 때문에 유사 배열 객체(array-like object)처럼 다뤄야한다.
다음 예시처럼 우회하는 순회 방법을 사용하면 된다.
순회 예제 1 - index 기반 for문 방식 (기본)
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key!);
console.log(`${key}: ${value}`);
}
length 속성 + key(index) 메서드 조합으로 순회
순회 예제 2 - Object.keys() (가장 깔끔하고 안전한 방식)
Object.keys(localStorage).forEach(key => {
console.log(`${key}: ${localStorage.getItem(key)}`);
});
Object.keys() 는 저장된 키만 반환하기 때문에 내장 메서드와 충돌하지 않음
키만 순회하므로 가장 안전하고 직관적
순회 예제 3 - for...in (사용 시 주의 - hasOwnProperty() 필요)
for (let key in localStorage) {
if (!localStorage.hasOwnProperty(key)) continue;
console.log(`${key}: ${localStorage.getItem(key)}`);
}
for...in 을 사용할 경우 getItem, setItem 등 내장 프로퍼티까지 순회한다.
반드시 hasOwnProperty() 로 체크 후에 값을 가져와야 한다.
Type 주의
키-값 쌍 모두 string 타입으로 저장되기 때문에 다른 자료형을 저장하려고 하면 자동으로 문자열로 변환되어버린다.
주의 예제 1 - 객체가 강제로 string으로 변환되는 경우
localStorage.setItem('user', { name: 'Kim' } as any); // X 잘못된 사용
console.log(localStorage.getItem('user')); // [object Object]
주의 예제 2 - 숫자, 불리언, null 등
| 123 | "123" | 숫자 → 문자열 |
| true | "true" | 불리언 → 문자열 |
| null | "null" | null → 문자열 |
| {} | "[object Object]" | 객체 → 문자열 (⚠️ JSON 사용 필요) |
| [] | "" | 빈 배열 → 빈 문자열 |
| undefined | "undefined" | 문자열 "undefined"로 저장됨 |
그래서 객체나 배열 저장 시 반드시 JSON 직렬화가 필요하다.
const user = { name: 'Kim', age: 28 };
// 저장 (직렬화)
localStorage.setItem('user', JSON.stringify(user));
// 불러오기 (역직렬화)
const stored = JSON.parse(localStorage.getItem('user')!);
console.log(stored.name); // Kim
참고: 이 방식에서 age의 값은 number로 잘 복원된다.
그래서, 웹 스토리지를 사용하기 좋은 경우는?
공통 경우
웹 스토리지는 클라이언트(브라우저) 측에서만 필요한 데이터를 저장할 때 적합하다.
다음과 같은 경우를 살펴볼 수 있다.
- 서버에 전송하지 않아도 되는 민감하지 않은 정보를 다룰 때 (반면 쿠키는 바로 서버로 전송된다)
- 클라이언트 내에서만 관리되는 UI 상태나 사용자 설정
- 재방문, 새로고침 등에서도 상태를 유지해야 할 때
- 네트워크나 서버 상태와 무관하게 임시 저장이 필요한 경우
로컬 스토리지를 사용하기 좋은 경우와 세션 스토리지를 사용하기 좋은 경우
로컬스토리지
브라우저를 닫거나 탭을 종료해도 값이 유지되어야 하는 경우에 적합하다.
사용 사례
| 사용자 설정값 저장 | 다크모드, 언어 선택, 폰트 크기 등 |
| 장바구니, 최근 본 상품 등 | 로그인하지 않아도 유지되어야 할 상태 |
| 비로그인 사용자 입력값 | 회원가입 도중 입력값 임시 저장 등 |
| 브라우저 간 창/탭 상태 공유 | storage 이벤트를 활용한 로그아웃 동기화 등 |
세션 스토리지
현재 탭 내에서만 잠시 보존하고 싶은 경우에 적합하다.
사용 사례
| 일회성 작업 중 상태 저장 | 예: 비회원 문의 작성, 미완료 결제정보 등 |
| 탭 간 구분이 필요한 작업 | 다중 탭 간 데이터 충돌을 방지해야 할 때 |
| 로그인 직후 전달된 임시 플래그 | 예: "회원가입 성공" 같은 일시적 안내 메시지 유지 등 |
'개발 > 개발 아카이브' 카테고리의 다른 글
| URL 파라미터 정리하기: JavaScript와 React에서 (0) | 2025.12.30 |
|---|---|
| 동기화 안 되는 main-develop, PR Cherry-pick 전략으로 배포 프로세스 개선해보기 (1) | 2025.10.18 |
| 디바운스(debounce)와 쓰로틀(throtte) 그리고 디바운스 적용기 (4) | 2025.08.08 |
| JavaScript 소수점 시리즈 - ceil, round, floor, trunc (1) | 2025.08.07 |
| 간단하게 예제로 알아보는 코드의 자유도 (0) | 2025.02.13 |