Bài 13. Web Storage và các Web API hữu ích

Trình duyệt cung cấp rất nhiều API sẵn có. Bài này giới thiệu nhóm hay dùng nhất: localStorage/sessionStorage, Intersection Observer, Clipboard, Geolocation, Notification và FormData.

45 phútTrung cấp
Bạn sẽ học được
  • Lưu dữ liệu phía trình duyệt bằng Web Storage
  • Theo dõi phần tử xuất hiện bằng Intersection Observer
  • Dùng Clipboard, Geolocation, Notification
  • Đọc form nhanh bằng FormData
Thuật ngữ cần biết
Web Storage
Kho khóa–giá trị của trình duyệt (khoảng 5 MB).
Same-origin
Dữ liệu chỉ truy cập được bởi cùng giao thức, tên miền, cổng.
Observer
Đối tượng theo dõi thay đổi và gọi callback.
Permission
Quyền người dùng cấp cho trang (vị trí, thông báo).

Khái niệm và lý thuyết

localStorage lưu lâu dài, sessionStorage mất khi đóng tab; cả hai chỉ lưu chuỗi và hoạt động đồng bộ. Dữ liệu lớn hoặc có cấu trúc nên dùng IndexedDB. Các API nhạy cảm (vị trí, thông báo, clipboard đọc) yêu cầu HTTPS và sự đồng ý của người dùng.

localStorage

const KHOA = "cai-dat";
function luu(obj) { localStorage.setItem(KHOA, JSON.stringify(obj)); }
function doc() {
  try { return JSON.parse(localStorage.getItem(KHOA)) ?? {}; }
  catch { return {}; }
}
luu({ cheDoToi: true, coChu: 16 });
document.body.classList.toggle("dark", doc().cheDoToi);
// Đồng bộ giữa các tab
window.addEventListener("storage", e => { if (e.key === KHOA) location.reload(); });

Intersection Observer

const io = new IntersectionObserver(entries => {
  for (const e of entries) {
    if (e.isIntersecting) {
      e.target.src = e.target.dataset.src;  // tải ảnh lười
      io.unobserve(e.target);
    }
  }
}, { rootMargin: "200px" });
document.querySelectorAll("img[data-src]").forEach(img => io.observe(img));

Ứng dụng: tải ảnh lười, cuộn vô hạn, hiệu ứng khi phần tử xuất hiện. Hiệu quả hơn nhiều so với lắng nghe sự kiện scroll.

Clipboard, vị trí, thông báo

await navigator.clipboard.writeText("Đã sao chép!");

navigator.geolocation.getCurrentPosition(
  p => console.log(p.coords.latitude, p.coords.longitude),
  err => console.warn(err.message));

if (await Notification.requestPermission() === "granted") {
  new Notification("Tự Học Tin", { body: "Bạn có bài học mới" });
}

FormData

form.addEventListener("submit", e => {
  e.preventDefault();
  const duLieu = Object.fromEntries(new FormData(form));
  console.log(duLieu); // { hoTen: "...", email: "..." }
});
Mẹo hay

Tra cứu mức hỗ trợ của trình duyệt trên caniuse.com và tài liệu MDN Web Docs (có bản tiếng Việt một phần).

Lưu ý

Không lưu mật khẩu, token đăng nhập dài hạn trong localStorage: mã độc XSS có thể đọc được. Token phiên nên đặt trong cookie HttpOnly do máy chủ quản lý.

Thực hành
  1. Làm nút chuyển chế độ sáng/tối, ghi nhớ bằng localStorage.
  2. Tải ảnh lười cho trang có 30 ảnh bằng Intersection Observer.
  3. Thêm nút “Sao chép mã” cho mọi khối pre trên trang.
  4. Hiển thị tọa độ hiện tại và liên kết mở Google Maps.
Tóm tắt bài học
  • localStorage/sessionStorage lưu chuỗi, dùng JSON cho đối tượng.
  • Intersection Observer thay cho sự kiện scroll.
  • API nhạy cảm cần HTTPS và quyền.
  • FormData đọc form nhanh chóng.