0
0
Lập trình
Admin Team
Admin Teamtechmely

Đồng bộ nhiều tab trong ứng dụng trình duyệt

Đăng vào 4 tháng trước

• 5 phút đọc

Đồng bộ nhiều tab trong ứng dụng trình duyệt

Khi bạn mở cùng một ứng dụng trong nhiều tab trên cùng một trình duyệt, việc giữ cho các tab này đồng bộ là rất quan trọng. Hãy tưởng tượng về cổng thông tin ngân hàng trực tuyến của bạn. Nếu bạn đăng nhập ở một tab và sau đó cố gắng mở cùng một cổng trong tab khác, tab đầu tiên thường sẽ hiển thị thông báo “phiên đã hết hạn” hoặc tự động đăng xuất bạn.

Đó là một ví dụ điển hình về đồng bộ hóa tab.

Vấn đề tôi gặp phải

Trong trường hợp của tôi, vấn đề là đồng bộ hóa xác thực.

Khi ứng dụng được mở trong nhiều tab, nếu người dùng đăng xuất ở một tab, các tab khác vẫn cố gắng sử dụng token truy cập đã hết hạn. Vì token không còn hợp lệ, tất cả các cuộc gọi API trong các tab đó đều thất bại cho đến khi người dùng làm mới thủ công.

Giải pháp

Ý tưởng rất đơn giản:

  1. Sử dụng localStorage như một trạng thái chia sẻ giữa các tab (vì nó có thể truy cập từ tất cả các tab cùng nguồn).
  2. Giữ một khóa đặc biệt (gọi là changeInAuth) trong localStorage mà được cập nhật mỗi khi có đăng nhập hoặc đăng xuất.
  3. Trong mỗi tab, lắng nghe thay đổi đối với khóa này bằng cách sử dụng sự kiện storage. Khi phát hiện sự thay đổi, xóa bất kỳ dữ liệu không hợp lệ nào từ sessionStorage và tải lại trang để các tab có thể lấy token và dữ liệu người dùng mới.

Bước 1: Thêm listener cho sự kiện storage trong App.tsx

typescript Copy
useEffect(() => {
  const handleLocalStorageChange = (event: StorageEvent) => {
    // Kiểm tra xem khóa auth có thay đổi không
    if (event.key === "changeInAuth") {
      // Xóa dữ liệu phiên
      sessionStorage.clear();

      // Tải lại trang
      window.location.reload();
    }
  };

  window.addEventListener("storage", handleLocalStorageChange);

  // Luôn dọn dẹp listener
  return () => {
    window.removeEventListener("storage", handleLocalStorageChange);
  };
}, []);

Ở đây, chúng ta đang nói với trình duyệt:

"Nếu bất kỳ tab nào cập nhật khóa changeInAuth trong localStorage, hãy tải lại tab này."

Bước 2: Cập nhật localStorage trong quá trình đăng nhập

typescript Copy
const login = async (userCreds) => {
  try {
    // Gọi API xác thực
    // Lưu token, thông tin người dùng, v.v. vào sessionStorage hoặc cookies

    // Kích hoạt sự kiện đồng bộ cho các tab khác
    localStorage.setItem("changeInAuth", Date.now().toString());
  } catch (error) {
    console.error("Đăng nhập thất bại:", error);
  }
};

Bước 3: Cập nhật localStorage trong quá trình đăng xuất

typescript Copy
const logout = async () => {
  // Gọi API đăng xuất
  // Xóa token, thông tin người dùng, và sessionStorage/cookies

  // Kích hoạt sự kiện đồng bộ cho các tab khác
  localStorage.setItem("changeInAuth", Date.now().toString());
};

Cách hoạt động

  • Mỗi khi có đăng nhập hoặc đăng xuất, một timestamp duy nhất được lưu trữ trong localStorage dưới khóa changeInAuth.
  • Tất cả các tab đều lắng nghe các thay đổi đối với khóa này.
  • Khi phát hiện sự thay đổi, các tab sẽ xóa dữ liệu phiên cũ và tải lại.
  • Sau khi tải lại, chúng sẽ lấy token mới và đồng bộ với backend.

Bằng cách này, ứng dụng có thể:

  1. Giữ cho tất cả các tab đồng bộ.
  2. Xử lý các phiên người dùng đơn lẻ một cách chính xác.
  3. Tự động chuyển sang người dùng đúng khi có ai đó đăng nhập/đăng xuất.

Các thực tiễn tốt nhất

  • Sử dụng localStorage một cách cẩn thận: Hãy đảm bảo bạn không lưu trữ thông tin nhạy cảm trong localStorage, vì nó có thể bị truy cập từ bất kỳ tab nào.
  • Kiểm tra khả năng hoạt động trên tất cả các trình duyệt: Một số trình duyệt có thể có cách xử lý sự kiện storage khác nhau.

Những cạm bẫy thường gặp

  • Không xử lý đúng sự kiện storage: Đảm bảo rằng bạn đã thêm listener cho sự kiện storage đúng cách để không bỏ lỡ bất kỳ thay đổi nào.
  • Quên xóa dữ liệu phiên: Nếu không xóa dữ liệu phiên đúng cách, người dùng có thể gặp phải tình trạng không đồng bộ giữa các tab.

Mẹo hiệu suất

  • Giảm thiểu số lần tải lại: Hãy chú ý đến cách bạn xử lý tải lại trang. Nếu có thể, hãy chỉ tải lại phần cần thiết thay vì tải lại toàn bộ trang.
  • Tối ưu hóa các cuộc gọi API: Sử dụng caching hoặc các phương pháp tối ưu khác để giảm tải cho server khi nhiều tab cùng truy cập.

Giải quyết sự cố

Nếu bạn gặp phải vấn đề khi các tab không đồng bộ:

  1. Kiểm tra xem listener cho sự kiện storage đã được thêm đúng cách chưa.
  2. Đảm bảo rằng bạn đang cập nhật localStorage mỗi khi có thay đổi về xác thực.
  3. Xem lại cấu trúc dữ liệu trong sessionStorage để đảm bảo không có dữ liệu cũ nào làm gián đoạn.

Kết luận

Sự kiện storage là một tính năng rất hữu ích của trình duyệt, và trong nhiều trường hợp, vài dòng mã là đủ để giải quyết những gì có thể trở thành một vấn đề rất khó chịu. Hãy thử áp dụng giải pháp này trong ứng dụng của bạn và xem sự khác biệt.

Câu hỏi thường gặp

1. Có cách nào khác để đồng bộ hóa dữ liệu giữa các tab không?
Có, bạn có thể sử dụng WebSockets hoặc các công nghệ khác để đồng bộ hóa dữ liệu theo thời gian thực.

2. LocalStorage có an toàn không?
LocalStorage không an toàn cho việc lưu trữ thông tin nhạy cảm. Nên sử dụng sessionStorage hoặc cookies có bảo mật hơn cho thông tin nhạy cảm.

Hy vọng bài viết này sẽ giúp bạn hiểu rõ hơn về cách đồng bộ hóa nhiều tab trong ứng dụng trình duyệt của mình.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào