W raz z pojawieniem się HTML5 dostaliśmy nowe narzędzia mogące rozwiązać odwieczne problemy z przechowywaniem danych po stronie przeglądarki (offline). Mam tu na myśli localStorage i sessionStorage. Zaletą tych API jest możliwość rozszerzania powierzchni dostępnej na dane użytkownika (domyślnie 5 MB w Chrome) w stosunku do ograniczonego rozmiaru cookies wynoszącego 4096 bajtów. Dodatkową wadą cookies jest również to że są przesyłane w nagłówku HTTP podczas każdego requestu, co w przypadku składowania większej ilości danych nie jest wskazane.
LocalStorage w przeciwieństwie to sessionStorage pamięta wszystkie dane dopóki ich ręcznie nie usuniemy, np. poprzez wyczyszczenie cache przeglądarki.
Dane zgromadzone w localStorage są dostępne w przeglądrce jako window.localStorage, gdzie od razu można zauważyć, że zapisane obiekty i tablice są serializowane do stringów, co prowadzi do tego, że wykonywanie skomplikowanych operacji na pamięci wewnętrznej przeglądarki jest co najmniej upierdliwe. Specyfikacja HTML5 zapewnia nam w tym miejscu dwa API, które możemy wykorzystać do potraktowania localStorage jako transakcyjnej bazy danych. Są nimi WebSQL oraz IndexedDB, które zostało dodane na późniejszym etapie prac nad HTML5 i jest niestety wspierane tylko przez najnowsze przeglądarki. W mojej opinii najlepszym sposobem na zarządzanie localStorage przy pomocy IndexedDB lub WebSQL jest wykorzystanie jednej z kilku dostępnych w sieci bibliotek. Ja przećwiczyłem Dexie.js , którą gorąco polecam (możemy ją pobrać zarówno npm’em jak i bower’em).
Poniżej przykład dodawania i odczytywania danych:
let db = new Dexie(“TestowaBaza”); //stworzenie nowej bazy danych db.version(1).stores({ //dodanie nowej tabeli i zdefiniowanie jej pól pracownicy: “imie,nazwisko,wiek” }); db.open().catch((error) => { //otwarcie bazy danych i obsłużenie ew. błędu console.log(“błąd połączenia, ” + error); }); db.pracownicy.add({ //dodanie nowego pracownika imie: “Marcin”, nazwisko: “Nowak”, wiek: 28 }); db.pracownicy.where(‘imie’).equals(“Marcin”).each((pracownik) => { //lista pracowników console.log(pracownik); });
Wygląda to bardzo przejrzyście, prawda ?
Na koniec chciałbym wspomnieć jeszcze o pracy aplikacji w trybie offline (brak połączenia z backendem). HTML5 pozwala na zdefiniowanie pliku cache manifest, który definiuje źródła wymagane do pracy aplikacji oraz reguły postępowania w przypadku ich braku. Przykładowo mamy plik JS który odpowiada za zapis danych do bazy (backendowej). W sytuacji kiedy jest ona niedostępna możemy ten plik podmienić innym, który zapisze nasze dane do localStorage, dopóki nie będzie wznowione połączenie z Internetem. Do prawidłowego działania cache manifest wymagana jest odpowiednia konfiguracja serwera HTTP. W moim przypadku był to Apache, więc cała konfiguracja sprowadziła się do odkomentowania linii w httpd.conf:
addType text/cache-manifest .appcache Przykładowy plik cache manifest wygląda tak: CACHE MANIFEST # Rev 3 -- wersja cache CACHE: -- cachowane źródła index.html pics/logo.png stylesheet.css FALLBACK: -- co ma się wydarzyć jeżeli nie ma dostępu do źródła *.html /offline.html
Pliczek ten musimy podpiąć do naszego index.html w ten sposób:
Podczas testowania trybu offline w chromie polecam URL: chrome://appcache-internals. Przyda się jeżeli chcemy uniknąć problemów z aktualizowaniem zawartości naszych plików JS :).
Reasumując mam nadzieję, że ten artykuł zapobiegnie tworzeniu kolejnych aplikacji które bezmyślnie “uderzają” ajaxem do backendu w celu pobrania danych zmieniających się raz na rok.