Khi xây dựng ứng dụng web, một trong những câu hỏi phổ biến nhất mà lập trình viên gặp phải là: "Tôi nên lưu dữ liệu này ở đâu - localStorage, sessionStorage, hay Cookie?" Ba công cụ này đều cho phép trình duyệt lưu trữ dữ liệu phía client, nhưng chúng khác nhau đáng kể về thời gian sống, dung lượng, khả năng bảo mật và cách sử dụng. Bài viết này sẽ giúp bạn hiểu rõ bản chất của từng loại và biết khi nào nên dùng cái nào.

1. Cookie là gì?
Cookie ra đời từ những ngày đầu của web (năm 1994) với mục đích ban đầu là giúp máy chủ "nhớ" trạng thái của người dùng giữa các request, vì bản thân giao thức HTTP là stateless (không lưu trạng thái).
Đặc điểm chính
- Dung lượng: rất nhỏ, khoảng 4KB mỗi cookie.
- Thời gian sống: có thể tự đặt hạn (expires/max-age), hoặc sẽ mất khi đóng trình duyệt nếu không đặt hạn (session cookie).
- Gửi kèm request: đây là điểm khác biệt lớn nhất - cookie tự động được gửi kèm theo mọi HTTP request đến server (nếu cùng domain), kể cả khi tải ảnh, CSS, hay gọi API.
- Có thể cấu hình bảo mật:
HttpOnly,Secure,SameSite.
Cách sử dụng cơ bản
// Tạo cookie document.cookie = "username=Nguyen; max-age=3600; path=/; SameSite=Strict"; // Đọc cookie (dạng chuỗi, cần tự parse) console.log(document.cookie); // "username=Nguyen" // Xóa cookie (đặt thời gian hết hạn về quá khứ) document.cookie = "username=; max-age=0; path=/";
Vì sao Cookie vẫn quan trọng trong bảo mật?
Với cờ HttpOnly, cookie sẽ không thể truy cập bằng JavaScript (document.cookie sẽ không đọc được nó), giúp chống lại tấn công XSS đánh cắp token. Đây là lý do vì sao cookie (đặc biệt là HttpOnly cookie do server thiết lập) vẫn là lựa chọn phổ biến để lưu session token hoặc JWT trong các hệ thống yêu cầu bảo mật cao.
2. localStorage là gì?
localStorage là một phần của Web Storage API, ra đời từ HTML5, được thiết kế để lưu trữ dữ liệu lớn hơn và đơn giản hơn cookie.
Đặc điểm chính
- Dung lượng: khoảng 5-10MB tùy trình duyệt, lớn hơn cookie rất nhiều.
- Thời gian sống: tồn tại vĩnh viễn cho đến khi bị xóa thủ công (bởi code hoặc người dùng xóa cache), không tự hết hạn.
- Không gửi kèm request: dữ liệu chỉ nằm trên trình duyệt, không tự động gửi lên server, giúp giảm tải băng thông.
- Phạm vi: theo origin (domain + protocol + port), dùng chung cho mọi tab/cửa sổ cùng origin.
Cách sử dụng cơ bản
// Lưu dữ liệu
localStorage.setItem("theme", "dark");
// Lưu object (cần chuyển sang JSON)
localStorage.setItem("user", JSON.stringify({ name: "Nguyen", age: 25 }));
// Đọc dữ liệu
const theme = localStorage.getItem("theme");
const user = JSON.parse(localStorage.getItem("user"));
// Xóa một mục
localStorage.removeItem("theme");
// Xóa toàn bộ
localStorage.clear();Trường hợp sử dụng phổ biến
- Lưu theme (sáng/tối) người dùng đã chọn.
- Lưu giỏ hàng khi người dùng chưa đăng nhập.
- Lưu cài đặt giao diện, ngôn ngữ.
- Cache dữ liệu tĩnh để giảm số lần gọi API.
3. sessionStorage là gì?
sessionStorage có API gần như giống hệt localStorage, chỉ khác nhau ở vòng đời dữ liệu.
Đặc điểm chính
- Dung lượng: tương đương localStorage (~5-10MB).
- Thời gian sống: chỉ tồn tại trong một phiên (session) của tab trình duyệt đó. Khi đóng tab, dữ liệu sẽ mất.
- Không chia sẻ giữa các tab: mỗi tab có sessionStorage riêng, ngay cả khi cùng mở một trang web.
- Không gửi kèm request: giống localStorage.
Cách sử dụng cơ bản
// Lưu dữ liệu
sessionStorage.setItem("formStep", "2");
// Đọc dữ liệu
const step = sessionStorage.getItem("formStep");
// Xóa một mục
sessionStorage.removeItem("formStep");
// Xóa toàn bộ
sessionStorage.clear();Trường hợp sử dụng phổ biến
- Lưu tạm dữ liệu của một form nhiều bước (multi-step form) để không bị mất khi người dùng vô tình tải lại trang.
- Lưu trạng thái điều hướng tạm thời (ví dụ: vị trí cuộn, bộ lọc đang áp dụng) chỉ trong phiên làm việc hiện tại.
- Theo dõi hành vi người dùng trong một phiên truy cập (analytics tạm thời).
4. Bảng so sánh tổng quan
| Tiêu chí | Cookie | localStorage | sessionStorage |
|---|---|---|---|
| Dung lượng | ~4KB | ~5-10MB | ~5-10MB |
| Thời gian sống | Tùy chỉnh được (có thể vĩnh viễn) | Vĩnh viễn đến khi xóa | Mất khi đóng tab |
| Gửi kèm HTTP request | Có (tự động) | Không | Không |
| Truy cập từ JS | Có (trừ khi HttpOnly) |
Có | Có |
| Chia sẻ giữa các tab | Có | Có (cùng origin) | Không |
| Hỗ trợ trình duyệt cũ | Rất tốt | Tốt (HTML5+) | Tốt (HTML5+) |
| Phù hợp lưu token nhạy cảm | Có (với HttpOnly, Secure) |
Không khuyến nghị | Không khuyến nghị |
5. Vấn đề bảo mật cần lưu ý
Một sai lầm khá phổ biến là lưu access token hoặc thông tin nhạy cảm trực tiếp vào localStorage. Vì localStorage có thể truy cập tự do bằng JavaScript, nếu website bị dính lỗi XSS (Cross-Site Scripting), kẻ tấn công có thể chèn script để đọc toàn bộ dữ liệu trong localStorage, bao gồm cả token đăng nhập.
Vì vậy:
- Với dữ liệu nhạy cảm như session token: ưu tiên dùng cookie với cờ
HttpOnly+Secure+SameSite=Strict, để JavaScript không thể đọc được và cookie chỉ được gửi qua HTTPS. - Với dữ liệu không nhạy cảm (theme, ngôn ngữ, cài đặt UI): localStorage hoặc sessionStorage là lựa chọn hợp lý và tiện dụng hơn.
6. Vậy nên chọn cái nào?
Bạn có thể tự hỏi ba câu sau để đưa ra quyết định:
- Dữ liệu có cần gửi lên server ở mỗi request không? Nếu có => Cookie.
- Dữ liệu có cần tồn tại lâu dài, kể cả sau khi đóng trình duyệt không? Nếu có => localStorage.
- Dữ liệu chỉ cần dùng trong phiên làm việc hiện tại của một tab? => sessionStorage.
Và luôn nhớ nguyên tắc: dữ liệu càng nhạy cảm, càng nên tránh xa localStorage/sessionStorage và cân nhắc cookie HttpOnly hoặc các giải pháp quản lý phiên phía server.
Kết luận
localStorage, sessionStorage và Cookie không phải là ba lựa chọn cạnh tranh nhau mà thường được kết hợp sử dụng trong cùng một ứng dụng thực tế: cookie để quản lý phiên đăng nhập an toàn, localStorage để lưu cài đặt cá nhân hóa lâu dài, và sessionStorage để xử lý dữ liệu tạm thời trong một phiên làm việc. Hiểu rõ đặc tính của từng công cụ sẽ giúp bạn thiết kế ứng dụng vừa hiệu quả, vừa bảo mật hơn.








