로컬 스토리지와 세션 스토리지
지난 장에서는 웹 애플리케이션이 Fetch API를 통해 서버와 비동기적으로 통신하는 방법을 다뤘습니다.
서버에서 데이터를 받아 화면에 반영하는 흐름은 중요하지만, 상황에 따라서는 서버를 거치지 않고 클라이언트(브라우저) 내부에 데이터를 저장해야 합니다.
대표적으로 로그인 상태 유지, 설정 정보 저장, 장바구니 임시 보관, 오프라인 지원 같은 기능이 여기에 해당합니다.
과거에는 이런 클라이언트 저장 용도로 쿠키(Cookie)를 많이 사용했습니다. 하지만 쿠키는 용량 제한(약 4KB), 모든 HTTP 요청에 자동 전송되는 오버헤드, 다루기 불편한 API 같은 한계가 있습니다. ES5부터 도입된 웹 스토리지(Web Storage) API는 이 한계를 보완하며, 더 큰 저장 용량과 단순한 API를 제공합니다.
웹 스토리지 API는 크게 두 가지 유형을 제공합니다. 로컬 스토리지(Local Storage)와 세션 스토리지(Session Storage).
이 글에서는 두 스토리지의 특징과 사용법, 그리고 실제 적용 시나리오를 순서대로 정리합니다.
웹 스토리지 (Web Storage) 개요
웹 스토리지는 클라이언트 측에서 key-value 형태로 데이터를 저장할 수 있게 해주는 웹 API입니다.
이 API는 동일 출처(Same Origin) 정책을 따르며, 각 출처(도메인, 프로토콜, 포트)마다 별도의 저장 공간을 가집니다.
즉, example.com에서 저장한 데이터는 another.com에서 접근할 수 없습니다.
두 가지 주요 웹 스토리지 객체는 전역 Window 객체의 프로퍼티로 제공됩니다.
window.localStoragewindow.sessionStorage
이 두 객체는 동일한 메서드와 프로퍼티를 제공하지만, 데이터의 지속성(persistence)에서 차이가 있습니다.
로컬 스토리지 (Local Storage)
로컬 스토리지는 브라우저를 닫았다가 다시 열어도 데이터가 유지되는 영구적인 저장소입니다. 사용자가 명시적으로 데이터를 삭제하거나, 브라우저 캐시를 지우지 않는 한 데이터가 지속적으로 보존됩니다.
- 지속성: 영구적 (브라우저 종료 후에도 유지)
- 만료 기간: 없음 (수동 삭제 필요)
- 용량: 출처당 약 5MB ~ 10MB (브라우저마다 다름)
- 접근성: 동일 출처의 모든 탭/창에서 접근 가능
- 데이터 형식: 문자열(
string)만 저장 가능
로컬 스토리지 사용법
localStorage 객체는 setItem(), getItem(), removeItem(), clear(), key() 등의 메서드를 제공합니다.
localStorage.setItem(key, value)key: 데이터를 식별할 키 (문자열)value: 저장할 값 (문자열)value는 항상 문자열로 변환되어 저장됩니다. 객체나 배열을 저장하려면JSON.stringify()를 사용하여 문자열로 변환해야 합니다.
// 문자열 저장
localStorage.setItem('username', 'Alice');
localStorage.setItem('theme', 'dark');
// 객체 저장 (JSON.stringify 사용)
const userSettings = {
notifications: true,
language: 'ko'
};
localStorage.setItem('settings', JSON.stringify(userSettings));
console.log("로컬 스토리지에 데이터 저장됨.");localStorage.getItem(key)key: 조회할 데이터의 키- 저장된 문자열 값을 반환합니다. 값이 없으면
null을 반환합니다. - 저장했던 객체나 배열은
JSON.parse()를 사용하여 다시 객체나 배열로 변환해야 합니다.
const storedUsername = localStorage.getItem('username');
console.log("저장된 사용자 이름:", storedUsername); // 결과: Alice
const storedTheme = localStorage.getItem('theme');
console.log("저장된 테마:", storedTheme); // 결과: dark
// 객체 조회 (JSON.parse 사용)
const storedSettings = localStorage.getItem('settings');
if (storedSettings) {
const parsedSettings = JSON.parse(storedSettings);
console.log("저장된 설정:", parsedSettings); // 결과: {notifications: true, language: 'ko'}
}localStorage.removeItem(key)key: 삭제할 데이터의 키
localStorage.removeItem('theme');
console.log("테마 데이터 삭제됨.");
console.log("남은 사용자 이름:", localStorage.getItem('username')); // 결과: Alice
console.log("삭제된 테마:", localStorage.getItem('theme')); // 결과: nulllocalStorage.clear()- 해당 출처에 저장된 모든 로컬 스토리지 데이터를 삭제합니다.
localStorage.clear();
console.log("모든 로컬 스토리지 데이터 삭제됨.");
console.log("사용자 이름:", localStorage.getItem('username')); // 결과: nulllocalStorage.key(index) 또는 for...inlocalStorage.length로 저장된 항목의 개수를 알 수 있습니다.
localStorage.setItem('fruit', 'apple');
localStorage.setItem('drink', 'water');
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
console.log(`${key}: ${value}`);
}
/*
결과 예시:
fruit: apple
drink: water
*/
// 또는 for...in 루프 (비권장: 프로토타입 체인의 속성도 포함될 수 있음)
// for (let key in localStorage) {
// if (localStorage.hasOwnProperty(key)) {
// console.log(`${key}: ${localStorage.getItem(key)}`);
// }
// }로컬 스토리지 활용 시나리오
- 사용자 설정 저장: 테마(다크 모드/라이트 모드), 언어 설정, 알림 설정 등
- 로그인 정보(JWT 토큰 등): 로그인 상태를 유지하기 위한 토큰 저장
- 장바구니 정보(오프라인 유지): 사용자가 브라우저를 닫아도 장바구니 내용 유지
- 캐싱 데이터: 자주 사용되는 데이터를 클라이언트에 저장하여 서버 요청 감소 (API 응답 캐싱)
세션 스토리지 (Session Storage)
세션 스토리지는 로컬 스토리지와 동일한 API를 제공하지만, 데이터가 현재 브라우저 세션 동안만 유지됩니다. 즉, 사용자가 탭이나 브라우저 창을 닫으면 해당 세션 스토리지의 데이터는 자동으로 삭제됩니다.
- 지속성: 세션 동안만 유지 (탭/창 닫으면 삭제)
- 만료 기간: 세션 종료 시 (만료 기간 설정 불가)
- 용량: 출처당 약 5MB ~ 10MB (브라우저마다 다름)
- 접근성: 동일한 탭/창 내에서만 접근 가능 (다른 탭/창에서는 접근 불가, 새로고침은 유지)
- 데이터 형식: 문자열(
string)만 저장 가능
세션 스토리지 사용법
로컬 스토리지와 동일한 메서드를 사용합니다. localStorage 대신 sessionStorage 객체를 사용하면 됩니다.
// 데이터 저장
sessionStorage.setItem('tempMessage', '이 메시지는 현재 세션 동안만 유지됩니다.');
sessionStorage.setItem('lastVisitedPage', '/products/detail/123');
// 데이터 조회
const message = sessionStorage.getItem('tempMessage');
console.log("세션 저장 메시지:", message);
// 데이터 삭제
sessionStorage.removeItem('lastVisitedPage');
sessionStorage.clear(); // 현재 세션의 모든 데이터 삭제세션 스토리지 활용 시나리오
- 단일 세션 내 임시 데이터: 폼 입력값 임시 저장 (페이지 이동 후 다시 돌아왔을 때), 일회성 알림 메시지
- 단계별 마법사(Wizard) 형식의 데이터: 여러 단계로 이루어진 회원가입 폼에서 각 단계의 입력 데이터를 다음 단계로 넘기기 전까지 임시 저장
- 세션별 사용자 액션 추적: 특정 세션에서만 필요한 사용자 행동 로그
쿠키 (Cookie)와 웹 스토리지 비교 (간략)
| 특징 | 쿠키 (Cookie) | 로컬 스토리지 (Local Storage) | 세션 스토리지 (Session Storage) |
|---|---|---|---|
| 지속성 | 만료일 지정 가능 (영구적/세션) | 영구적 (브라우저 종료 후에도 유지) | 세션 동안만 유지 (탭/창 닫으면 삭제) |
| 용량 | 약 4KB | 5~10MB | 5~10MB |
| 서버 전송 | 모든 HTTP 요청 시 자동으로 서버로 전송 | 클라이언트에서만 접근 가능 (서버로 자동 전송 안됨) | 클라이언트에서만 접근 가능 (서버로 자동 전송 안됨) |
| 접근성 | 동일 출처의 모든 탭/창, 서버에서 접근 가능 | 동일 출처의 모든 탭/창에서 접근 가능 | 동일 출처의 동일 탭/창에서만 접근 가능 |
| API | 복잡 (document.cookie 문자열 파싱) | 간단 (setItem, getItem 등) | 간단 (setItem, getItem 등) |
| 주요 용도 | 사용자 인증 (세션 ID), 추적 | 사용자 설정, 캐시, 로그인 토큰, 오프라인 데이터 | 폼 데이터, 임시 상태, 일회성 메시지 |
결론: 대부분의 클라이언트 측 데이터 저장에는 웹 스토리지를 사용하는 것이 쿠키보다 유리합니다. 쿠키는 주로 서버에서 읽고 써야 하는 사용자 인증(세션 ID)이나 트래킹 정보 등에 제한적으로 사용됩니다.
스토리지 활용 요약
이 절에서는 로컬 스토리지(Local Storage)와 세션 스토리지(Session Storage)의 차이를 정리했습니다.
핵심은 지속성 범위입니다. 로컬 스토리지는 브라우저를 다시 열어도 유지되고, 세션 스토리지는 현재 탭/세션 범위에서만 유지됩니다.
또한 두 스토리지가 setItem(), getItem(), removeItem(), clear() 중심의 동일한 API를 제공하지만, 저장 단위가 문자열이라는 제약이 있다는 점도 확인했습니다.
그래서 객체나 배열을 저장할 때는 JSON.stringify()와 JSON.parse()를 함께 사용해야 합니다.
쿠키와 비교하면 웹 스토리지는 저장 용량과 API 사용성이 더 좋고, HTTP 요청마다 데이터가 자동 전송되지 않아 불필요한 트래픽도 줄일 수 있습니다. 다음 절에서는 DOM 조작과 이벤트 핸들링으로 화면 반응을 다루는 방법을 이어서 살펴보겠습니다.