Lưu Trữ Dữ Liệu Với localStorage và sessionStorage
Lưu trữ dữ liệu luôn là một trong những bước quan trọng nhất quyết định lớn đến hiệu năng của sản phẩm. Thông thường chúng ta lưu trữ dữ liệu vào cơ sở dữ liệu qua các hệ quản trị cơ sở dữ liệu hay lưu trữ dữ liệu thông qua cookie, session. Hôm nay Suntech sẽ giới thiệu với các bạn 2 cách để lưu trữ dữ liệu trong trình duyệt đó là localStorage và sessionStorage.
Một số điểm thú vị về localStorage và sessionStorage
- Dữ liệu vẫn tồn tại sau khi làm mới trang (cho
sessionStorage
) và thậm chí khi khởi động lại toàn bộ trình duyệt (cholocalStorage
). - Chúng còn có thể lưu trữ dữ liệu tương đối lớn 2-5MB và tất nhiên có các cài đặt để định cấu hình điều đó.
- Chúng không gửi thông tin lên server như Cookie nên bảo mật tốt hơn. Máy chủ cũng không thể thao tác với các đối tượng lưu trữ thông qua tiêu đề HTTP. Vì vậy mọi thứ đều được thực hiện bằng JavaScript.
Demo localStorage
Trước khi đến demo của localStorage thì chúng ta hãy xem qua các đặc điểm chính của localStorage
- Tất cả các tabs và cửa sổ trong trình duyệt nếu như có cùng một nguồn thì chúng có thể chia sẻ thông tin với nhau.
- Dữ liệu vẫn còn sau khi trình duyệt khởi động lại hay thậm chí vẫn còn khi ta khởi động lại hệ điều hành.
Ví dụ khi bạn chạy đoạn code dưới đây:
localStorage.setItem('test', 1);
… Sau đó đóng hoặc mở trình duyệt hoặc chỉ mở cùng một trang trong một cửa sổ khác, sau đó bạn có thể nhận được giá trị vừa rồi như sau:
alert( localStorage.getItem('test') ); // 1
Tất nhiên chúng phải có chung 1 nguồn có thể là domain, port hay protocol và đường dẫn chúng có thể khác nhau.
Access localStorage
Để access localStorage chúng ta có thê sử dụng getting/setting như sau:
// set key
localStorage.test = 2;
// get key
alert( localStorage.test ); // 2
// remove key
delete localStorage.test;
Tuy nhiên cách này không được khuyến khích dùng bởi:
- Nếu key là do người dùng tạo thì nó có thể là bất cứ thứ gì như
length
haytoString
,..... Trong trường hợp này thì mọi thứ vẫn có thể hoạt động tốt với getItem/setItem tuy nhiên object-like access lại lỗi.
let key = 'length';
localStorage[key] = 5; // Error, can't assign length
- Khi có
storage
event, nó kích hoạt khi chúng ta sửa đổi dữ liệu. Điều đó không xảy ra đối với việc object-like access. Chúng ta sẽ thấy điều đó dưới đây.
Looping over keys
Như chúng ta đã thấy, các phương pháp này cung cấp chức năng "get/set/remove
". Vậy làm thế nào để lấy tất cả các giá trị hoặc key đã lưu?
Thật không may, các đối tượng lưu trữ không thể lặp lại.
Chúng ta có thể lặp lại chúng như trên một mảng:
for(let i=0; i<localStorage.length; i++) {
let key = localStorage.key(i);
alert(`${key}: ${localStorage.getItem(key)}`);
}
Hoặc lặp lại các key, nhưng cũng có thể xuất ra một số trường tích hợp sẵn mà chúng ta không cần:
// bad try
for(let key in localStorage) {
alert(key); // shows getItem, setItem and other built-in stuff
}
Strings only
Hãy nhớ key và value phải là string. Nếu là bất kỳ loại nào khác thì nó sẽ tự động được chuyển đổi thành string:
sessionStorage.user = {name: "John"};
alert(sessionStorage.user); // [object Object]
Chúng ta cũng có thể sử dụng JSON
để lưu trữ các đối tượng:
sessionStorage.user = JSON.stringify({name: "John"});
// sometime later
let user = JSON.parse( sessionStorage.user );
alert( user.name ); // John
Ngoài ra, chúng ta có thể xâu chuỗi toàn bộ đối tượng lưu trữ, ví dụ: cho mục đích gỡ lỗi:
// added formatting options to JSON.stringify to make the object look nicer
alert( JSON.stringify(localStorage, null, 2) );
sessionStorage
sessionStorage
được sử dụng ít hơn so với localStorage
.
sessionStorage
chỉ tồn tại trong tab trình duyệt hiện tại.- Một tab khác có cùng trang sẽ có khả năng lưu trữ khác.
- Nhưng nó được chia sẻ giữa các iframe trong cùng một tab (giả sử chúng đến từ cùng một nguồn gốc).
- Dữ liệu vẫn tồn tại khi làm mới trang, nhưng nó sẽ bị mất khi đóng hoặc mở tab. Ví dụ bạn hãy chạy mã này:
sessionStorage.setItem('test', 1);
Sau đó hãy refresh trang. Bây giờ bạn vẫn có thể nhận lại dữ liệu:
alert( sessionStorage.getItem('test') ); // after refresh: 1
Nhưng nếu bạn mở cùng một trang trong một tab khác và thử lại nó, đoạn mã trên sẽ trả về null.
Đó là bởi vì sessionStorage
không chỉ bị ràng buộc với cả tab trình duyệt. Vì lý do đó, sessionStorage
được sử dụng một cách tiết kiệm.
Storage event
Khi dữ liệu được cập nhật trong localStorage
hoặc sessionStorage
, thì storage event kích hoạt thuộc tính:
key
- key đã được thay đổi (null
nếu.clear()
được gọi).oldValue
- giá trị cũ (null
nếu key mới được thêm vào).newValue
- giá trị mới (null
nếu key bị xóa).url
- url của tài liệu đã cập nhật.storageArea
- hoặclocalStorage
hoặcsessionStorage
đối tượng cập nhật.
Điều quan trọng là: sự kiện kích hoạt trên tất cả window
nơi bộ nhớ có thể truy cập được, ngoại trừ đối tượng đã gây ra nó. Bạn hãy tưởng tượng bạn có hai cửa sổ với cùng một trang web vậy, localStorage
sẽ chia sẻ giữa 2 cửa sổ đó.
Bạn có thể mở bất kì trang web nào trong hai cửa sổ trình duyệt để kiểm tra. Nếu cả 2 cửa sổ đều nhận window.onstorage
, thì mỗi cửa sổ sẽ phản ứng về các cập nhật đã xảy ra trong cửa sổ kia.
// triggers on updates made to the same storage from other documents
window.onstorage = event => {
if (event.key != 'now') return;
alert(event.key + ':' + event.newValue + " at " + event.url);
};
localStorage.setItem('now', Date.now());
Tổng kết:
localStorage và sessionStorage cho phép lưu trữ key và value trong trình duyệt
- Key và value phải là string
- Giới hạn lưu trữ khoảng 5MB tùy từng trình duyệt
- Khả năng lưu trữ vô thời hạn
- Dữ liệu bị ràng buộc bởi domain/port/protocol
Cảm ơn các bạn đã tìm hiểu về localStorage và sessionStorage. Hẹn gặp lại các bạn trong các bài viết tiếp theo!