웹 스토리지 완전 정복: LocalStorage & SessionStorage 활용법과 예제

현대 웹 애플리케이션은 사용자 경험을 향상시키기 위해 다양한 데이터를 클라이언트 측(브라우저)에 저장합니다. 로그인 상태 유지, 장바구니 정보, 사용자 설정 등 많은 정보가 웹 페이지를 닫거나 다시 방문했을 때도 유지되어야 합니다. 이때 핵심적인 역할을 하는 것이 바로 **웹 스토리지(Web Storage)**입니다. 이 포스팅에서는 웹 스토리지의 두 가지 주요 유형인 **LocalStorage**와 **SessionStorage**의 개념, 사용법, 그리고 실제 활용 예시를 상세히 알아보겠습니다.

🧩 웹 스토리지란?

웹 스토리지(Web Storage API)는 웹 애플리케이션이 사용자 브라우저 내에 데이터를 로컬로 저장할 수 있는 방법을 제공하는 기술입니다. 기존에 클라이언트 측 데이터를 저장하던 쿠키(Cookies)의 단점을 보완하며 등장했습니다.

웹 스토리지가 쿠키보다 좋은 점

  • 더 큰 저장 용량: 쿠키는 약 4KB의 제한된 용량을 가지지만, 웹 스토리지는 도메인당 약 5MB 이상(브라우저마다 다름)의 훨씬 큰 용량을 제공합니다. 이 정도면 대부분의 클라이언트 측 데이터를 저장하기에 충분합니다.
  • 서버 전송 없음: 쿠키는 모든 HTTP 요청 시 자동으로 서버로 전송되어 네트워크 트래픽을 증가시키고 성능에 영향을 줄 수 있습니다. 웹 스토리지 데이터는 명시적으로 요청하지 않는 한 서버로 전송되지 않으므로, 네트워크 부하가 줄어듭니다.
  • 간단한 API: 쿠키는 복잡한 파싱 및 직렬화 과정이 필요한 반면, 웹 스토리지는 setItem(), getItem() 등 직관적이고 쉬운 JavaScript API를 제공합니다.

📚 LocalStorage와 SessionStorage의 차이점

웹 스토리지는 데이터를 저장하는 방식과 생명 주기에 따라 크게 두 가지 객체로 나뉩니다.

  • LocalStorage (로컬 스토리지)

    • 영구적인 저장: LocalStorage에 저장된 데이터는 사용자가 브라우저를 닫거나 컴퓨터를 재시작해도 **영구적으로 유지**됩니다.
    • 삭제 방법: 명시적으로 JavaScript 코드를 통해 삭제하거나, 브라우저 설정에서 캐시/사이트 데이터를 지워야만 삭제됩니다.
    • 활용 예시: 자동 로그인 정보, 사용자 테마 설정(다크 모드/라이트 모드), 장바구니 정보, 사용자 기본 설정 등 웹사이트를 재방문해도 유지되어야 하는 데이터 저장.
  • SessionStorage (세션 스토리지)

    • 세션 기간 동안 저장: SessionStorage에 저장된 데이터는 **현재 브라우저 세션(탭 또는 창)이 유지되는 동안에만 존재**합니다.
    • 삭제 시점: 사용자가 해당 탭이나 창을 닫으면 데이터는 자동으로 삭제됩니다. 새로고침 시에는 유지됩니다.
    • 활용 예시: 일회성 로그인 상태, 결제 과정 중 임시 데이터, 비로그인 상태의 장바구니 (페이지 이동 시 유지, 브라우저 닫으면 삭제), 일시적인 사용자 입력값 등 세션이 종료되면 사라져야 하는 데이터 저장.

간단 비교표

특징 LocalStorage SessionStorage
데이터 유지 기간 영구적 (사용자가 직접 삭제 또는 브라우저 데이터 삭제 시까지) 브라우저 세션(탭/창)이 유지되는 동안
다른 탭/창 접근 동일 출처(Origin)의 다른 탭/창에서 접근 가능 동일 출처 내에서도 다른 탭/창에서 접근 불가능 (각 세션은 독립적)
데이터 전송 서버로 자동 전송되지 않음 서버로 자동 전송되지 않음
저장 용량 약 5MB 이상 약 5MB 이상
주요 사용 사례 자동 로그인, 사용자 설정, 장바구니 등 일시적 로그인, 결제 정보 등 세션 한정 데이터

⚙️ 웹 스토리지 공통 API 사용법

LocalStorage와 SessionStorage는 동일한 API를 사용하므로, 사용법을 한 번 익히면 두 가지 모두에 적용할 수 있습니다. 데이터를 저장할 때는 키(key)와 값(value)의 형태로 저장하며, **값은 반드시 문자열(String) 형태**여야 합니다. 객체나 배열 같은 복잡한 데이터를 저장하려면 JSON 문자열로 변환해야 합니다.

  • 데이터 저장: setItem(key, value)

    지정된 키에 값을 저장합니다. 값이 문자열이 아니라면 자동으로 문자열로 변환되지만, 객체나 배열은 `JSON.stringify()`를 사용하는 것이 안전합니다.

    
    // LocalStorage에 문자열 저장
    localStorage.setItem('username', 'codingdoitwolf');
    
    // SessionStorage에 숫자 저장 (자동으로 문자열 "123"으로 변환됨)
    sessionStorage.setItem('userId', 123);
    
    // LocalStorage에 객체 저장 (JSON.stringify() 사용 필수!)
    const userSettings = { theme: 'dark', notifications: true };
    localStorage.setItem('settings', JSON.stringify(userSettings));
    
    // SessionStorage에 배열 저장 (JSON.stringify() 사용 필수!)
    const cartItems = ['itemA', 'itemB'];
    sessionStorage.setItem('cart', JSON.stringify(cartItems));
          
  • 데이터 가져오기: getItem(key)

    지정된 키에 해당하는 값을 가져옵니다. 값이 없으면 null을 반환합니다. 객체나 배열로 저장된 데이터는 `JSON.parse()`를 사용하여 다시 객체/배열로 변환해야 합니다.

    
    // LocalStorage에서 문자열 가져오기
    const username = localStorage.getItem('username'); // 'codingdoitwolf'
    
    // SessionStorage에서 숫자 가져오기 (문자열 "123"으로 가져와짐)
    const userId = sessionStorage.getItem('userId'); // "123" (문자열)
    const parsedUserId = parseInt(userId); // 숫자로 변환
    
    // LocalStorage에서 객체 가져오기 (JSON.parse() 사용 필수!)
    const settingsString = localStorage.getItem('settings');
    const userSettings = JSON.parse(settingsString);
    // userSettings는 { theme: 'dark', notifications: true } 객체가 됨
    
    // SessionStorage에서 배열 가져오기 (JSON.parse() 사용 필수!)
    const cartString = sessionStorage.getItem('cart');
    const cartItems = JSON.parse(cartString);
    // cartItems는 ['itemA', 'itemB'] 배열이 됨
          
  • 데이터 삭제: removeItem(key)

    지정된 키에 해당하는 데이터를 삭제합니다.

    
    // LocalStorage에서 'username' 데이터 삭제
    localStorage.removeItem('username');
    
    // SessionStorage에서 'userId' 데이터 삭제
    sessionStorage.removeItem('userId');
          
  • 모든 데이터 삭제: clear()

    해당 스토리지(LocalStorage 또는 SessionStorage)에 저장된 모든 데이터를 삭제합니다.

    
    // LocalStorage의 모든 데이터 삭제
    localStorage.clear();
    
    // SessionStorage의 모든 데이터 삭제
    sessionStorage.clear();
          
  • 키 가져오기: key(index)

    지정된 인덱스에 해당하는 키(key) 이름을 가져옵니다. 모든 저장된 키를 반복할 때 유용합니다.

    
    // LocalStorage에 저장된 첫 번째 키 가져오기
    const firstKey = localStorage.key(0);
    
    // LocalStorage에 저장된 모든 키와 값 출력
    for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i);
        const value = localStorage.getItem(key);
        console.log(`Key: ${key}, Value: ${value}`);
    }
          
  • 저장된 데이터 개수: length

    해당 스토리지에 저장된 데이터(키-값 쌍)의 개수를 반환합니다.

    
    const numberOfItems = localStorage.length; // LocalStorage에 저장된 항목 수
          

💡 웹 스토리지 활용 예제

실제 웹 개발에서 LocalStorage와 SessionStorage가 어떻게 활용될 수 있는지 구체적인 예제를 통해 살펴보겠습니다.

예제 1: 사용자 다크 모드 설정 저장 (LocalStorage)

사용자가 다크 모드를 선택하면 그 설정을 LocalStorage에 저장하여, 브라우저를 닫았다가 다시 열어도 설정이 유지되도록 합니다.


<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>다크 모드 설정 예제</title>
  <style>
    body { font-family: sans-serif; transition: background-color 0.3s, color 0.3s; }
    body.dark-mode { background-color: #333; color: #f2f2f2; }
    .container { max-width: 600px; margin: 50px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px; }
  </style>
</head>
<body>
  <div class="container">
    <h2>다크 모드 설정</h2>
    <button id="toggleDarkMode">다크 모드 전환</button>
    <p>이 페이지를 닫았다가 다시 열어도 설정이 유지됩니다.</p>
  </div>

  <script>
    const toggleButton = document.getElementById('toggleDarkMode');
    const body = document.body;

    // 페이지 로드 시 LocalStorage에서 설정 불러오기
    const savedMode = localStorage.getItem('themeMode');
    if (savedMode === 'dark') {
      body.classList.add('dark-mode');
    }

    // 버튼 클릭 시 모드 전환 및 LocalStorage에 저장
    toggleButton.addEventListener('click', () => {
      if (body.classList.contains('dark-mode')) {
        body.classList.remove('dark-mode');
        localStorage.setItem('themeMode', 'light');
      } else {
        body.classList.add('dark-mode');
        localStorage.setItem('themeMode', 'dark');
      }
    });
  </script>
</body>
</html>
  

예제 2: 임시 장바구니 데이터 저장 (SessionStorage)

사용자가 상품을 장바구니에 담았을 때, 다른 페이지로 이동해도 장바구니 내용이 유지되지만, 브라우저 탭을 닫으면 사라지게 하고 싶을 때 SessionStorage를 사용할 수 있습니다.


<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>임시 장바구니 예제</title>
  <style>
    .container { max-width: 600px; margin: 50px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px; }
    #cartList { list-style: none; padding: 0; }
    #cartList li { margin-bottom: 5px; }
  </style>
</head>
<body>
  <div class="container">
    <h2>임시 장바구니</h2>
    <input type="text" id="itemName" placeholder="상품명">
    <button id="addItem">상품 추가</button>
    <button id="clearCart">장바구니 비우기</button>
    <h3>장바구니 목록:</h3>
    <ul id="cartList"></ul>
    <p><small>브라우저 탭을 닫으면 장바구니 내용이 사라집니다.</small></p>
  </div>

  <script>
    const itemNameInput = document.getElementById('itemName');
    const addItemButton = document.getElementById('addItem');
    const clearCartButton = document.getElementById('clearCart');
    const cartList = document.getElementById('cartList');

    // SessionStorage에서 장바구니 불러와 화면에 표시
    function loadCart() {
      cartList.innerHTML = ''; // 목록 초기화
      const savedCart = sessionStorage.getItem('currentCart');
      const items = savedCart ? JSON.parse(savedCart) : [];

      items.forEach(item => {
        const li = document.createElement('li');
        li.textContent = item;
        cartList.appendChild(li);
      });
    }

    // 페이지 로드 시 장바구니 불러오기
    loadCart();

    // 상품 추가 버튼 클릭 이벤트
    addItemButton.addEventListener('click', () => {
      const newItem = itemNameInput.value.trim();
      if (newItem) {
        const savedCart = sessionStorage.getItem('currentCart');
        const items = savedCart ? JSON.parse(savedCart) : [];
        items.push(newItem);
        sessionStorage.setItem('currentCart', JSON.stringify(items));
        itemNameInput.value = ''; // 입력 필드 초기화
        loadCart(); // 장바구니 업데이트
      }
    });

    // 장바구니 비우기 버튼 클릭 이벤트
    clearCartButton.addEventListener('click', () => {
      sessionStorage.clear(); // SessionStorage의 모든 데이터 삭제
      loadCart(); // 장바구니 업데이트
    });
  </script>
</body>
</html>
  

⚠️ 웹 스토리지 사용 시 주의사항

웹 스토리지는 편리하지만, 몇 가지 주의할 점이 있습니다.

  • 보안: 웹 스토리지는 XSS(Cross-Site Scripting) 공격에 취약할 수 있습니다. 중요한 민감 정보(예: 비밀번호, 신용카드 번호)는 웹 스토리지에 직접 저장해서는 안 됩니다. 서버에서 안전하게 관리하거나 암호화된 형태로 저장하고, 반드시 HTTPS를 사용해야 합니다.
  • 동기적(Synchronous) 작업: 웹 스토리지의 모든 작업(setItem, getItem 등)은 동기적으로 수행됩니다. 이는 데이터를 읽고 쓰는 동안 메인 스레드가 차단될 수 있다는 의미입니다. 매우 큰 데이터를 저장하거나 자주 접근할 경우 웹 애플리케이션의 성능에 영향을 줄 수 있으니 주의해야 합니다.
  • 문자열만 저장 가능: 앞에서 언급했듯이, 웹 스토리지는 문자열만 저장할 수 있습니다. 객체나 배열을 저장하려면 `JSON.stringify()`로 직렬화(Serialization)하고, 가져올 때는 `JSON.parse()`로 역직렬화(Deserialization)해야 합니다.
  • 만료 기한 없음: LocalStorage는 쿠키와 달리 만료 기한을 설정할 수 없습니다. 따라서 불필요한 데이터는 removeItem()이나 clear()를 통해 직접 삭제해야 합니다. SessionStorage는 탭/창 종료 시 자동 삭제되므로 이 문제는 해당되지 않습니다.
  • 용량 제한: 브라우저마다 다르지만, 도메인당 5MB~10MB 정도의 용량 제한이 있습니다. 이보다 더 큰 데이터를 저장해야 한다면 IndexedDB 같은 다른 클라이언트 측 스토리지 솔루션을 고려해야 합니다.

✨ 결론

웹 스토리지는 클라이언트 측 데이터를 효율적으로 관리하고 사용자 경험을 향상시키는 데 매우 유용한 도구입니다. 특히 LocalStorage는 영구적인 데이터 저장에, SessionStorage는 세션 기반의 임시 데이터 저장에 적합합니다.

이 포스팅에서 다룬 API 사용법과 예시를 통해 웹 스토리지의 강력함을 이해하고 실제 프로젝트에 효과적으로 적용하시길 바랍니다. 다만, 보안 및 성능상의 주의사항을 항상 염두에 두시고 적절한 상황에 맞는 스토리지 솔루션을 선택하는 것이 중요합니다.