localStorage và sessionStorage

localStorage và sessionStorage

Trình duyệt cung cấp hai cơ chế lưu trữ phía client:

  localStorage sessionStorage
Thời gian tồn tại Vĩnh viễn (đến khi xoá) Đến khi đóng tab/cửa sổ
Phạm vi Cùng origin, tất cả tab Cùng tab
Dung lượng ~5–10 MB / origin ~5 MB

API cơ bản (giống nhau cho cả hai)

// Ghi
localStorage.setItem('key', 'value');
localStorage.setItem('user', JSON.stringify({ name: 'Lan', age: 25 }));

// Đọc
const val  = localStorage.getItem('key');        // → 'value' hoặc null
const user = JSON.parse(localStorage.getItem('user'));

// Xoá
localStorage.removeItem('key');
localStorage.clear();   // xoá tất cả

// Số lượng mục
localStorage.length;

Chỉ lưu được chuỗi. Dùng JSON.stringify() / JSON.parse() để lưu object hay array.

Trường hợp sử dụng phổ biến

  • Lưu theme (dark/light) người dùng đã chọn
  • Lưu ngôn ngữ ưa thích
  • Draft bài viết hoặc form chưa gửi
  • Giỏ hàng đơn giản (không cần auth)
  • Ngăn hiện popup lần 2 (firstVisit flag)

Ví dụ: Bộ đếm với localStorage

Kết quả
<div style="font-family:sans-serif;text-align:center;padding:1rem">
  <p style="font-size:1rem;color:#666">Giá trị được lưu trong localStorage</p>
  <div style="font-size:3rem;font-weight:bold;color:#4472c4;margin:0.5rem 0"
    id="countDisplay">0</div>
  <div style="display:flex;justify-content:center;gap:0.5rem;flex-wrap:wrap">
    <button id="dec">➖ Giảm</button>
    <button id="inc">➕ Tăng</button>
    <button id="reset">🔄 Reset</button>
  </div>
  <p style="font-size:0.82rem;color:#999;margin-top:0.75rem">
    Tải lại trang → giá trị vẫn còn đây!
  </p>
</div>
button {
  padding: 0.45rem 1rem;
  border: none;
  border-radius: 6px;
  background: #4472c4;
  color: white;
  cursor: pointer;
  font-size: 0.95rem;
  transition: background 0.2s;
}
button:hover { background: #2f5396; }
#reset { background: #6c757d; }
#reset:hover { background: #495057; }
const KEY     = 'demo_counter';
const display = document.getElementById('countDisplay');

function getCount() {
  return parseInt(localStorage.getItem(KEY) || '0', 10);
}

function setCount(n) {
  localStorage.setItem(KEY, n);
  display.textContent = n;
  display.style.color = n > 0 ? '#2ecc71' : n < 0 ? '#e74c3c' : '#4472c4';
}

// Khởi tạo từ localStorage
setCount(getCount());

document.getElementById('inc').addEventListener('click',   () => setCount(getCount() + 1));
document.getElementById('dec').addEventListener('click',   () => setCount(getCount() - 1));
document.getElementById('reset').addEventListener('click', () => setCount(0));

Ví dụ: Notepad tự động lưu

Kết quả
<div style="font-family:sans-serif;padding:0.5rem">
  <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:0.5rem">
    <strong>📝 Ghi chú</strong>
    <div style="display:flex;gap:0.4rem">
      <button id="clearNote">Xoá</button>
      <span id="saveStatus" style="font-size:0.8rem;color:#999;line-height:2"></span>
    </div>
  </div>
  <textarea id="notepad" placeholder="Gõ ghi chú của bạn... (tự động lưu)"
    style="width:100%;height:150px;padding:0.6rem;font-size:0.95rem;
           border:1px solid #ccc;border-radius:6px;resize:vertical;box-sizing:border-box">
  </textarea>
  <p style="font-size:0.8rem;color:#aaa;margin-top:0.3rem">
    Nội dung lưu trong <code>localStorage</code> — không mất khi tải lại.
  </p>
</div>
const KEY      = 'demo_notepad';
const notepad  = document.getElementById('notepad');
const status   = document.getElementById('saveStatus');
const clearBtn = document.getElementById('clearNote');

// Tải ghi chú đã lưu
notepad.value = localStorage.getItem(KEY) || '';

// Debounce + auto-save
let saveTimer;
notepad.addEventListener('input', () => {
  status.textContent = 'Đang lưu...';
  clearTimeout(saveTimer);
  saveTimer = setTimeout(() => {
    localStorage.setItem(KEY, notepad.value);
    status.textContent = '✅ Đã lưu';
  }, 600);
});

clearBtn.addEventListener('click', () => {
  localStorage.removeItem(KEY);
  notepad.value = '';
  status.textContent = 'Đã xoá';
});

Bình luận