LocalStorage는 웹 브라우저에 클라이언트 측 데이터를 간단하게 저장할 수 있는 Web Storage API이다. 문자열 형태의 데이터를 key-value 쌍으로 저장하며, 브라우저를 종료해도 데이터가 유지된다. 이는 쿠키와 달리 용량이 크고(보통 5~10MB), 서버로 자동 전송되지 않는다는 점이 특징이다.
// 기본 저장
localStorage.setItem('username', 'John');
// 객체 저장 (JSON 직렬화)
const user = { name: 'John', age: 30 };
localStorage.setItem('user', JSON.stringify(user));
// 문자열 불러오기
const username = localStorage.getItem('username');
console.log(username); // 'John'
// 존재하지 않는 키는 null 반환
const notExist = localStorage.getItem('nonexistent');
console.log(notExist); // null
// 객체 불러오기 (JSON 파싱)
const userJson = localStorage.getItem('user');
const user = JSON.parse(userJson);
console.log(user.name); // 'John'
// 특정 항목 삭제
localStorage.removeItem('username');
// 모든 항목 삭제
localStorage.clear();
// 특정 인덱스의 키 가져오기
const key = localStorage.key(0);
console.log(key);
// 전체 키 확인
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
console.log(key);
}
// 또는
Object.keys(localStorage).forEach(key => {
console.log(key, localStorage.getItem(key));
});
// 다크 모드 설정 저장
function setTheme(theme) {
localStorage.setItem('theme', theme);
applyTheme(theme);
}
// 앱 로드 시 사용자 설정 복원
function loadTheme() {
const savedTheme = localStorage.getItem('theme') || 'light';
applyTheme(savedTheme);
}
loadTheme();
const form = document.querySelector('form');
const inputs = form.querySelectorAll('input, textarea');
// 사용자 입력 감지 및 저장
inputs.forEach(input => {
// 페이지 로드 시 저장된 값 복원
const savedValue = localStorage.getItem(input.name);
if (savedValue) {
input.value = savedValue;
}
// 입력 변경 시 저장
input.addEventListener('change', () => {
localStorage.setItem(input.name, input.value);
});
});
// 제출 시 저장된 데이터 삭제
form.addEventListener('submit', () => {
inputs.forEach(input => {
localStorage.removeItem(input.name);
});
});
class ShoppingCart {
constructor() {
this.cartKey = 'shopping_cart';
}
addItem(product) {
const cart = this.getCart();
const existingItem = cart.find(item => item.id === product.id);
if (existingItem) {
existingItem.quantity++;
} else {
product.quantity = 1;
cart.push(product);
}
this.saveCart(cart);
}
removeItem(productId) {
const cart = this.getCart();
const filtered = cart.filter(item => item.id !== productId);
this.saveCart(filtered);
}
getCart() {
const saved = localStorage.getItem(this.cartKey);
return saved ? JSON.parse(saved) : [];
}
saveCart(cart) {
localStorage.setItem(this.cartKey, JSON.stringify(cart));
}
clear() {
localStorage.removeItem(this.cartKey);
}
}
// 사용
const cart = new ShoppingCart();
cart.addItem({ id: 1, name: 'Laptop', price: 999 });
LocalStorage는 브라우저 개발자 도구에서 쉽게 접근 가능하므로 비밀번호, 신용카드 번호, 토큰 등을 저장하면 안 된다.
// ❌ 위험
localStorage.setItem('password', userPassword);
localStorage.setItem('token', authToken);
// ✅ 권장
// 세션 토큰은 HttpOnly 쿠키에 저장
// 중요 정보는 서버에서만 관리
모든 데이터의 합이 5~10MB를 초과하면 안 된다.
function getStorageSize() {
let total = 0;
for (let key in localStorage) {
if (localStorage.hasOwnProperty(key)) {
total += localStorage[key].length + key.length;
}
}
return total; // 바이트 단위
}
저장소가 가득 찬 경우나 비활성화된 경우 처리해야 한다.
function safeSetItem(key, value) {
try {
localStorage.setItem(key, value);
} catch (error) {
if (error.name === 'QuotaExceededError') {
console.error('❌ LocalStorage 용량 초과');
} else if (error.name === 'SecurityError') {
console.error('❌ LocalStorage 접근 불가');
}
}
}
사용자 입력으로 LocalStorage에 저장된 데이터를 다시 출력할 때는 반드시 이스케이프 처리하자.
// ❌ 위험
document.innerHTML = localStorage.getItem('userInput');
// ✅ 안전
document.textContent = localStorage.getItem('userInput');
| 기능 | LocalStorage | SessionStorage | 쿠키 | IndexedDB |
|---|---|---|---|---|
| 📦 용량 | 5~10MB | 5~10MB | 4KB | 훨씬 큼 |
| ⏰ 만료 | 없음 | 탭 종료 시 | 설정 가능 | 없음 |
| 🚀 서버 전송 | 없음 | 없음 | 자동 | 없음 |
| ⚡ 접근 속도 | 빠름 | 빠름 | 빠름 | 느림 |
| 🔍 복잡한 쿼리 | 불가 | 불가 | 불가 | 가능 |
LocalStorage는 간단한 클라이언트 데이터 저장에 최적화된 도구이다. 사용자 설정, 캐시 데이터, UI 상태 같은 비민감 정보에 활용하면 좋다. 다만 보안이 중요한 정보는 절대 저장하지 말고, 성능과 용량 제한을 고려해서 사용하자. 복잡한 데이터는 IndexedDB를 사용하는 것을 권장한다.