TypeScript và StorageManager
Bài viết này giải thích về TypeScript và StorageManager.
Chúng tôi cung cấp các ví dụ thực tế để giải thích về TypeScript và StorageManager.
YouTube Video
TypeScript và StorageManager
StorageManager là gì?
StorageManager là một API cho phép ứng dụng web ước tính được dung lượng lưu trữ đang sử dụng và dung lượng còn lại khả dụng. Nó còn cung cấp phương thức yêu cầu lưu trữ lâu dài (persist()) để ngăn ngừa việc dữ liệu bị xóa tự động bởi người dùng hoặc trình duyệt. Điều này cho phép bạn kiểm soát xem có đủ dung lượng trống hay không, hoặc dữ liệu có bị xóa tự động hay không, ví dụ như khi lưu trữ lượng lớn dữ liệu trong IndexedDB cho các ứng dụng offline.
Phát hiện tính năng
Đầu tiên, hãy kiểm tra xem trình duyệt có hỗ trợ navigator.storage không.
1// TypeScript: feature detection for StorageManager
2function supportsStorageManager(): boolean {
3 return typeof navigator !== "undefined" &&
4 typeof navigator.storage !== "undefined" &&
5 typeof navigator.storage.estimate === "function";
6}
7
8// Example usage
9if (supportsStorageManager()) {
10 console.log("StorageManager is supported.");
11} else {
12 console.warn("StorageManager not supported. Falling back to localStorage or IndexedDB.");
13}- Hàm này kiểm tra tính khả dụng của API StorageManager theo từng bước.
- Vì
navigator.storagekhông tồn tại trên một số trình duyệt như Safari, nên cần kiểm tra sự tồn tại của nó một cách an toàn bằng cách sử dụngtypeof.
Ước tính dung lượng lưu trữ (estimate())
Sau khi kiểm tra chức năng với supportsStorageManager(), lấy thông tin sử dụng (usage) và giới hạn lưu trữ (quota) từ navigator.storage.estimate().
1// TypeScript: safely get storage estimate
2async function getStorageEstimate(): Promise<{ usage: number; quota: number } | null> {
3 if (!supportsStorageManager()) {
4 console.warn("StorageManager not supported.");
5 return null;
6 }
7
8 const estimate = await navigator.storage.estimate();
9 return { usage: estimate.usage ?? 0, quota: estimate.quota ?? 0 };
10}
11
12// Example usage
13getStorageEstimate().then(result => {
14 if (result) {
15 console.log(`Usage: ${result.usage} bytes / Quota: ${result.quota} bytes`);
16 }
17});- Hàm này luôn hoạt động an toàn và trả về
nullnếu trình duyệt không hỗ trợ. usagevàquotalà con số ước tính và có thể khác nhau giữa các trình duyệt.
Yêu cầu lưu trữ lâu dài (persist())
Sử dụng persist() để yêu cầu lưu trữ lâu dài, giúp dữ liệu quan trọng (ví dụ: bộ nhớ cache offline) không bị trình duyệt tự động xóa. Tuy nhiên, nó không phải lúc nào cũng thành công trên mọi môi trường.
1// TypeScript: safely request persistent storage
2async function requestPersistence(): Promise<boolean> {
3 if (!supportsStorageManager()) {
4 console.warn("StorageManager not supported.");
5 return false;
6 }
7
8 if (typeof navigator.storage.persist !== "function") {
9 console.warn("persist() not available in this browser.");
10 return false;
11 }
12
13 try {
14 const granted = await navigator.storage.persist();
15 return Boolean(granted);
16 } catch (err) {
17 console.error("persist() error:", err);
18 return false;
19 }
20}
21
22// Example usage
23requestPersistence().then(granted => {
24 console.log("Persistence granted?", granted);
25});- Nếu
persist()thành công, dữ liệu sẽ không bị trình duyệt tự động xóa, trừ khi người dùng tự xóa thủ công. Tuy nhiên, các yêu cầu này có thể bị từ chối tùy vào hành động của người dùng hoặc cài đặt trình duyệt.
Kiểm tra dung lượng lưu trữ khả dụng trước khi lưu dữ liệu
Kiểm tra dung lượng trống trước khi lưu dữ liệu lớn để tránh lỗi ghi dữ liệu (QuotaExceededError).
1// TypeScript: ensure enough space before writing
2async function ensureSpaceAndWrite(neededBytes: number, writeFn: () => Promise<void>): Promise<boolean> {
3 const estimate = await getStorageEstimate();
4 if (!estimate) {
5 console.warn("Cannot check storage space. Proceeding without validation.");
6 await writeFn();
7 return true;
8 }
9
10 const free = estimate.quota - estimate.usage;
11 if (free < neededBytes) {
12 console.warn(`Not enough space. Free: ${free} bytes, needed: ${neededBytes} bytes.`);
13 return false;
14 }
15
16 await writeFn();
17 return true;
18}
19
20// Example usage
21ensureSpaceAndWrite(10 * 1024 * 1024, async () => {
22 console.log("Saving large data...");
23});- Bằng cách kiểm tra dung lượng lưu trữ còn lại trước khi lưu, bạn có thể giảm rủi ro bị gián đoạn ghi do thiếu dung lượng.
Xử lý localStorage một cách an toàn về kiểu dữ liệu trong TypeScript
localStorage tiện lợi để lưu dữ liệu cấu hình nhẹ và các thông tin tương tự.
Lớp dưới đây sử dụng generic để tạo một lớp bao an toàn về kiểu dữ liệu.
1// TypeScript: typed localStorage wrapper
2type Serializer<T> = {
3 serialize: (v: T) => string;
4 deserialize: (s: string) => T;
5};
6
7class TypedLocalStorage<K extends string, V> {
8 constructor(private storage: Storage, private serializer: Serializer<V>) {}
9
10 set(key: K, value: V): void {
11 this.storage.setItem(key, this.serializer.serialize(value));
12 }
13
14 get(key: K): V | null {
15 const raw = this.storage.getItem(key);
16 if (raw === null) return null;
17 try {
18 return this.serializer.deserialize(raw);
19 } catch {
20 return null;
21 }
22 }
23
24 remove(key: K): void {
25 this.storage.removeItem(key);
26 }
27
28 clear(): void {
29 this.storage.clear();
30 }
31}
32
33// Example usage
34const jsonSerializer: Serializer<any> = {
35 serialize: v => JSON.stringify(v),
36 deserialize: s => JSON.parse(s),
37};
38
39const appStorage = new TypedLocalStorage<'theme' | 'token', any>(localStorage, jsonSerializer);
40appStorage.set('theme', { dark: true });
41console.log(appStorage.get('theme'));- Lớp này giúp giảm rủi ro lưu hoặc lấy dữ liệu với kiểu không đúng.
Lưu ý thực tế và các thực hành tốt nhất
-
Luôn kiểm tra trình duyệt có hỗ trợ StorageManager không Vì StorageManager là một API tương đối mới, luôn xác nhận sự tồn tại của nó trước khi sử dụng.
-
Chú ý đến giới hạn lưu trữ và tính tương thích Giá trị trả về từ
estimate()thay đổi tùy trình duyệt và chỉ là con số ước tính. -
Thiết kế với các API bất đồng bộ
estimate()vàpersist()là các API bất đồng bộ dựa trên promise. Thiết kế mã của bạn để không làm chặn giao diện người dùng. -
Lưu ý về bảo mật Không lưu trữ thông tin nhạy cảm như access token trong
localStorage. Cân nhắc sử dụng cookie HttpOnly hoặc mã hóa nếu có thể. -
Thiết kế dự phòng Nếu
supportsStorageManager()trả về false, hãy cung cấp logic để chuyển sang chỉ sử dụnglocalStoragehoặcIndexedDB.
Tóm tắt
Nhờ phát hiện tính năng bằng supportsStorageManager(), bạn có thể hỗ trợ an toàn mọi môi trường, kiểm tra dung lượng đã dùng và tổng dung lượng bằng navigator.storage.estimate(), và yêu cầu lưu trữ lâu dài với persist(). Trong TypeScript, hãy sử dụng các hàm bao và định nghĩa kiểu để viết mã rõ ràng, an toàn. Quy trình cơ bản là: kiểm tra sự tồn tại, ước tính, yêu cầu lưu trữ lâu dài, và kiểm tra dung lượng trước khi ghi vào bộ nhớ.
Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.