2025-09-05 00:28
-
로컬 스토리지는 웹 브라우저에 데이터를 영구적으로 저장하는 기술로, Key-Value 쌍으로 작동하며 약 5-10MB의 용량을 제공합니다.
-
사용자의 설정(예: 다크 모드), 비로그인 장바구니, 입력하던 폼 내용 임시 저장 등 다양한 곳에 활용되지만, 비밀번호 같은 민감 정보 저장에는 절대 사용하면 안 됩니다.
-
쿠키, 세션 스토리지와는 데이터의 만료 기간, 용량, 서버 전송 여부 등에서 뚜렷한 차이점을 가지므로 용도에 맞게 선택해야 합니다.
프론트엔드 개발자 필독 로컬 스토리지 A to Z 핸드북
웹 개발을 하다 보면 “사용자가 설정한 다크 모드를 브라우저를 껐다 켜도 유지하고 싶은데…” 혹은 “로그인하지 않은 사용자의 장바구니 정보를 어디에 저장하지?” 와 같은 고민을 마주하게 됩니다. 이때 가장 먼저 떠오르는 해결사 중 하나가 바로 ‘로컬 스토리지(Local Storage)‘입니다. 로컬 스토리지는 웹 브라우저에 데이터를 저장하는 아주 간단하고 강력한 방법입니다.
이번 핸드북에서는 로컬 스토리지가 왜 만들어졌는지 그 탄생 배경부터 시작해서, 내부 구조, 사용법, 그리고 실무에서 마주칠 수 있는 심화 내용과 모범 사례까지, 로컬 스토리지의 모든 것을 쉽고 깊이 있게 파헤쳐 보겠습니다.
1. 로컬 스토리지는 왜 만들어졌을까? (탄생 배경)
로컬 스토리지를 이해하려면 먼저 그 ‘선배’ 격인 ‘쿠키(Cookie)‘를 알아야 합니다. 과거 웹사이트는 사용자의 정보를 기억할 방법이 마땅치 않았습니다. 사용자가 페이지를 새로고침하거나 다른 페이지로 이동하면 모든 정보가 초기화되었죠. 이를 ‘Stateless(무상태)‘라고 합니다. 이 문제를 해결하기 위해 등장한 것이 쿠키입니다.
쿠키는 웹사이트가 사용자의 브라우저에 작은 텍스트 조각을 저장하는 기술입니다. 덕분에 로그인 상태를 유지하거나, ‘오늘 하루 이 팝업 보지 않기’ 같은 기능을 구현할 수 있게 되었습니다.
하지만 쿠키에게는 몇 가지 치명적인 단점이 있었습니다.
-
작은 용량: 약 4KB밖에 되지 않아 저장할 수 있는 정보의 양이 매우 제한적이었습니다.
-
서버 트래픽: 쿠키는 매번 HTTP 요청을 보낼 때마다 서버로 함께 전송됩니다. 서버에 필요 없는 정보까지 계속 보내니 불필요한 트래픽이 발생했습니다.
-
보안: 쿠키 정보는 조작되거나 탈취될 위험이 있었습니다.
이러한 쿠키의 단점을 보완하고, 순수하게 클라이언트(브라우저) 측에서만 사용할 데이터를 더 크고, 더 안전하고, 더 편리하게 저장하기 위해 HTML5 표준의 일부로 웹 스토리지(Web Storage) 기술이 등장했습니다. 그리고 웹 스토리지는 두 가지 저장소, 즉 로컬 스토리지와 세션 스토리지로 나뉩니다.
-
로컬 스토리지 (Local Storage): 데이터를 ‘영구적으로’ 저장합니다. 사용자가 직접 데이터를 삭제하거나 브라우저 캐시를 청소하지 않는 한 데이터는 사라지지 않습니다.
-
세션 스토리지 (Session Storage): 데이터를 ‘세션 기간’ 동안만 저장합니다. 즉, 브라우저 탭이나 창을 닫으면 데이터가 사라집니다.
비유하자면, 로컬 스토리지는 내 컴퓨터 하드디스크에 파일을 저장하는 것과 같고, 세션 스토리지는 컴퓨터 메모리(RAM)에 임시로 데이터를 올려두는 것과 비슷합니다. 쿠키는 매번 해외로 보낼 소포에 필수로 붙여야 하는 이름표 같은 존재고요.
2. 로컬 스토리지의 구조와 특징
로컬 스토리지는 매우 단순한 구조를 가지고 있습니다. 바로 ‘Key-Value’ 쌍입니다. 마치 사물함에 ‘열쇠(Key)‘로 ‘물건(Value)‘을 보관하는 것과 같습니다.
-
Key: 데이터에 접근하기 위한 고유한 이름입니다. (문자열)
-
Value: 저장하려는 실제 데이터입니다. (문자열)
여기서 가장 중요한 점은 Key와 Value 모두 반드시 ‘문자열(String)’ 형태여야 한다는 것입니다. 숫자, 배열, 객체 등 다른 타입의 데이터를 저장하려면 문자열로 변환하는 과정이 필요합니다.
로컬 스토리지의 주요 특징 요약
특징 | 설명 |
---|---|
데이터 형태 | Key-Value 쌍. Key와 Value 모두 반드시 문자열이어야 함. |
저장 용량 | 약 5MB ~ 10MB (브라우저마다 다름). 쿠키(4KB)보다 훨씬 큼. |
데이터 만료 | 영구적. 사용자가 직접 삭제하지 않는 한 데이터가 유지됨. |
데이터 범위 | 오리진(Origin)에 종속적. 프로토콜, 호스트, 포트가 모두 같아야 데이터 공유 가능. (예: https://a.com 과 https://b.com 은 데이터 공유 불가, http://a.com 과 https://a.com 도 공유 불가) |
서버와의 관계 | 서버로 데이터가 자동 전송되지 않음. 순수하게 클라이언트 측 저장소. |
API | 동기식(Synchronous)으로 작동. 데이터 요청 시 작업이 끝날 때까지 다른 스크립트 실행이 멈출 수 있음. |
로컬 스토리지 vs 세션 스토리지 vs 쿠키
세 가지 기술의 차이점을 명확히 이해하는 것은 매우 중요합니다.
구분 | 로컬 스토리지 (Local Storage) | 세션 스토리지 (Session Storage) | 쿠키 (Cookie) |
---|---|---|---|
만료 시점 | 영구적 (직접 삭제 전까지) | 브라우저 탭/창 닫을 때 | 지정된 만료일에 만료 |
용량 | 큼 (약 5-10MB) | 큼 (약 5MB) | 작음 (약 4KB) |
데이터 범위 | 오리진(Origin) | 오리진 + 탭/창 | 도메인 및 하위 도메인 |
서버 전송 | 전송 안 됨 | 전송 안 됨 | 매 HTTP 요청마다 전송 |
주요 용도 | 자동 로그인, 사용자 설정, 비로그인 장바구니 | 일회성 정보, 입력 폼 데이터 임시 저장 | 로그인 상태 유지(인증) |
API | localStorage.setItem() 등 | sessionStorage.setItem() 등 | document.cookie |
3. 로컬 스토리지 사용법 (API)
로컬 스토리지를 다루는 방법은 매우 직관적이고 간단합니다. window
객체에 포함되어 있어 window.localStorage
또는 줄여서 localStorage
로 바로 접근할 수 있습니다.
데이터 저장하기: setItem(key, value)
‘theme’이라는 Key에 ‘dark’라는 Value를 저장하는 예시입니다.
// 'theme'이라는 키로 'dark'라는 값을 저장
localStorage.setItem('theme', 'dark');
// 숫자나 객체를 저장하려면? 반드시 문자열로 변환해야 합니다.
const user = { name: 'Alice', id: 123 };
localStorage.setItem('user', JSON.stringify(user));
데이터 읽기: getItem(key)
‘theme’이라는 Key에 저장된 값을 가져옵니다. 만약 해당 Key가 존재하지 않으면 null
을 반환합니다.
// 'theme' 키에 해당하는 값을 가져옴
const currentTheme = localStorage.getItem('theme'); // "dark"
// 문자열로 변환했던 객체를 다시 원래 형태로 복원
const userString = localStorage.getItem('user');
const userObject = JSON.parse(userString); // { name: 'Alice', id: 123 }
데이터 삭제하기: removeItem(key)
특정 Key-Value 쌍을 삭제합니다.
// 'theme' 키와 값을 삭제
localStorage.removeItem('theme');
모든 데이터 삭제하기: clear()
로컬 스토리지에 저장된 모든 데이터를 삭제합니다.
localStorage.clear();
기타 API
-
key(index)
: 해당 인덱스(0부터 시작)에 위치한 Key의 이름을 반환합니다. -
length
: 로컬 스토리지에 저장된 항목의 개수를 반환합니다.
// 첫 번째 아이템의 키 이름 가져오기
const firstKey = localStorage.key(0);
// 저장된 아이템의 총 개수
const totalItems = localStorage.length;
4. 심화 내용 및 모범 사례
로컬 스토리지는 사용하기 쉽지만, 실무에서 제대로 활용하려면 몇 가지 주의사항과 팁을 알아야 합니다.
1. 절대 민감한 정보를 저장하지 마세요 (보안)
로컬 스토리지는 XSS (Cross-Site Scripting) 공격에 매우 취약합니다. XSS는 공격자가 악의적인 스크립트를 웹사이트에 삽입하여 다른 사용자의 브라우저에서 실행시키는 공격입니다. 만약 악성 스크립트가 실행되면, localStorage.getItem()
을 통해 저장된 모든 정보를 쉽게 탈취할 수 있습니다.
따라서 **비밀번호, 개인 정보, 인증 토큰(JWT 등)**과 같은 민감한 데이터는 절대 로컬 스토리지에 저장하면 안 됩니다. 인증 토큰은 HttpOnly
속성을 설정한 쿠키에 저장하는 것이 훨씬 안전합니다.
2. 객체와 배열은 반드시 JSON.stringify
/ JSON.parse
사용
앞서 강조했듯이 로컬 스토리지는 문자열만 저장할 수 있습니다. 객체나 배열을 그대로 저장하려고 하면 [object Object]
와 같은 의미 없는 문자열로 변환되어 저장됩니다.
const settings = { volume: 80, quality: 'high' };
// 잘못된 방법
localStorage.setItem('settings', settings); // "settings" 키에 "[object Object]"가 저장됨
// 올바른 방법
localStorage.setItem('settings', JSON.stringify(settings));
// 읽을 때도 변환 필요
const loadedSettings = JSON.parse(localStorage.getItem('settings'));
3. 동기적 작동으로 인한 성능 저하 주의
로컬 스토리지의 API는 동기식(Synchronous)으로 작동합니다. 이는 localStorage.setItem()
이나 getItem()
을 호출하면 해당 작업이 완료될 때까지 브라우저의 메인 스레드가 멈춘다는 것을 의미합니다.
대부분의 경우 데이터의 크기가 작아 문제가 되지 않지만, 만약 복잡하고 큰 데이터를 반복적으로 읽고 쓰는 작업을 한다면 UI 렌더링을 방해하여 사용자 경험을 해칠 수 있습니다. 이런 경우에는 비동기적으로 작동하는 IndexedDB와 같은 다른 브라우저 저장소 기술을 고려해야 합니다.
4. 브라우저 개발자 도구로 확인하기
대부분의 웹 브라우저는 개발자 도구(F12)를 통해 로컬 스토리지에 저장된 데이터를 쉽게 확인하고 수정할 수 있습니다.
- Chrome: 개발자 도구 > Application 탭 > Storage > Local Storage
이 기능을 활용하면 개발 중에 데이터가 올바르게 저장되고 있는지 쉽게 디버깅할 수 있습니다.
5. 실용적인 활용 사례
로컬 스토리지는 다음과 같은 시나리오에서 유용하게 사용될 수 있습니다.
-
UI 상태 유지: 다크/라이트 모드, 사이드바 열림/닫힘 상태 등 사용자가 설정한 UI 테마나 상태를 저장합니다.
-
비로그인 장바구니: 로그인하지 않은 사용자가 장바구니에 담은 상품 목록을 저장합니다.
-
입력 폼 데이터 임시 저장: 사용자가 긴 글을 작성하거나 복잡한 폼을 입력할 때, 페이지를 새로고침하거나 실수로 창을 닫아도 내용이 날아가지 않도록 주기적으로 데이터를 저장합니다.
-
최근 본 상품 목록: 사용자가 최근에 둘러본 상품이나 콘텐츠 목록을 보여줍니다.
-
데이터 캐싱: 자주 변경되지 않는 비민감성 데이터(예: 애플리케이션 설정 정보, 사용자 이름 등)를 캐싱하여 API 호출 횟수를 줄입니다.
결론
로컬 스토리지는 쿠키의 한계를 극복하고 클라이언트 측에 데이터를 쉽고 영구적으로 저장할 수 있게 해주는 강력한 도구입니다. Key-Value라는 단순한 구조, 넉넉한 용량, 그리고 간편한 API 덕분에 많은 프론트엔드 개발자에게 사랑받고 있습니다.
하지만 그 편리함 이면에는 보안 취약점과 동기적 작동이라는 한계도 명확히 존재합니다. 따라서 로컬 스토리지의 특징을 정확히 이해하고, 민감하지 않은 데이터를 저장하는 용도로 적재적소에 활용하는 지혜가 필요합니다.
이 핸드북을 통해 로컬 스토리지에 대한 자신감을 얻고, 여러분의 웹 애플리케이션을 한 단계 더 발전시키는 데 도움이 되었기를 바랍니다.