Розбір сховищ даних у браузері: від Cookies до IndexedDB

Розбір сховищ даних у браузері: від Cookies до IndexedDB

  • 20 грудня
  • читати 20 хв
Володимир Шайтан
Володимир Шайтан Senior Full Stack Developer у UKEESS Software House, Викладач Комп'ютерної школи Hillel.
Інна Овчаренко
Інна Овчаренко Junior Frontend Developer | React

Вебдодатки у нашому світі стають усе більш і більш інтерактивними та складнішими, що вимагає зберігання даних не тільки на сервері, але і на клієнтській стороні.

Для цього браузери надають розробникам безліч інструментів для локального зберігання даних, які допомагають поліпшити продуктивність і досвід користувача.

Локальні сховища дозволяють програмам зберігати дані прямо в браузері користувача, що позбавляє необхідності постійно звертатися до сервера. Це особливо корисно у випадках, коли програма має працювати офлайн або в умовах нестабільного інтернет-з'єднання.

У цій статті ми розглянемо основні типи сховищ на фронтенді, такі як sessionStorage, localStorage, cookies, Cache API, IndexedDB і Web SQL.

Ми пояснимо коли і як їх використовувати, а також надамо приклади коду для кожного з них. Розуміння цих інструментів допоможе вам ефективно працювати з даними, створювати швидші, стійкі та зручні для користувача програми.

SESSION STORAGE ТА LOCAL STORAGE

Почнемо з того, про що ви всі чули й, імовірніше за все, користувалися: SessionStorage та localStorage — це два типи вебсховищ, які дозволяють вебдодаткам зберігати дані на стороні клієнта. Попри те, що вони мають багато спільного, існують ключові відмінності, що визначають, коли і як слід використовувати кожне з них. Розглянемо їх особливості й відмінності докладніше.

SESSION STORAGE

SessionStorage призначене для зберігання даних під час сесії користувача. Це означає, що дані, збережені в sessionStorage, доступні лише під час відкритої вкладки або вікна браузера. Щойно вкладка або вікно закриваються, всі дані, що зберігаються в sessionStorage, видаляються.

Це робить sessionStorage ідеальним вибором для зберігання тимчасової інформації, такої як стан форм, які не потрібно зберігати після закриття вкладки.

Приклад використання sessionStorage:

// Збереження даних у sessionStorage
`sessionStorage.setItem('username', 'JohnDoe');`
// Отримання даних із sessionStorage
`const username = sessionStorage.getItem('username');
console.log(username);` // Виведе JohnDoe
// Видалення даних із sessionStorage
`sessionStorage.removeItem('username');`

LOCAL STORAGE

LocalStorage, на відміну від sessionStorage, призначене для тривалого зберігання даних. Дані, збережені в localStorage, залишаються доступними навіть після закриття вкладки або вікна браузера. Вони зберігаються доти, доки користувач не видаляє їх вручну або не очистить кеш браузера.

Це робить localStorage придатним для зберігання інформації, яка повинна бути доступна при повторних відвідуваннях вебпрограми, такої як налаштування користувача або збережені дані.

Приклад використання localStorage:

// Збереження даних у localStorage
`localStorage.setItem('theme', 'dark');`
// Отримання даних із localStorage
`const theme = localStorage.getItem('theme');
console.log(theme);` // Виведе dark
// Видалення даних із localStorage
`localStorage.removeItem('theme');`

ПОРІВНЯННЯ І ВИКОРИСТАННЯ

Хоча sessionStorage і localStorage мають різні цілі та час життя даних, вони обидва належать до категорії вебсховищ і мають схожий інтерфейс. Це дозволяє розробникам легко перемикатися між ними залежно від вимог програми, не заплутуючи відмінностей у використанні API.

Саме тому їх зручно розглядати разом. Розуміння їх відмінностей і схожостей допомагає вибрати найбільш слушний інструмент для конкретного завдання, забезпечуючи оптимальну роботу з даними на фронтенді.

COOKIES

Cookies — це один із найстаріших і найширше використовуваних способів зберігання даних на клієнтській стороні. Вони є невеликими шматочками даних, які вебсайт може зберігати на пристрої користувача та передавати разом із запитами до сервера.

Cookies використовуються для таких завдань, як автентифікація, збереження користувацьких переваг і відстеження активності на сайті.

Особливості Cookies:

  • Розмір та структура

Cookies обмежені за розміром (зазвичай не більше 4 KB на один cookie) і можуть зберігати лише рядки. Для зберігання складніших структур даних (наприклад, об'єктів або масивів) необхідно серіалізувати їх у рядок, використовуючи JSON.stringify().

  • Термін життя

Cookies можуть бути налаштовані на автоматичне видалення після певного часу. Термін життя можна ставити явно через параметр expires або max-age. Якщо термін не вказано, cookie буде видалена під час закриття браузера (сесійні cookies).

  • Передача на сервер

Одна з ключових особливостей cookies полягає в тому, що вони автоматично надсилаються серверу з кожним запитом HTTP до домену, з якого були встановлені. Це робить їх корисними для завдань, пов'язаних з автентифікацією (наприклад, зберігання сесійних ідентифікаторів), але також накладає обмеження на розмір даних, оскільки великі куки можуть уповільнити завантаження сторінок.

Приклад роботи з Cookies:

  • Читання Cookie

Читання cookie здійснюється через властивість document.cookie, яка повертає рядок, що містить усі cookies, розділені крапкою з комою.

// Отримання всіх cookies
`const cookies = document.cookie;`
`console.log(cookies); `// Приклад виведення: 'username=John Doe; theme=dark'
// Пошук конкретного cookie
``function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
console.log(getCookie('username'));`` // Виведе John Doe
  • Видалення Cookie

Щоб видалити cookie, його необхідно перезаписати з параметром expires у минулому:

// Видалення cookie
`document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";`
  • Додаткові параметри безпеки:

Cookies підтримують низку параметрів для поліпшення безпеки та контролю над передачею даних:

  • HttpOnly: обмежує доступ до cookie лише сервером, забороняючи доступ через JavaScript. Це допомагає запобігти атакам XSS (міжсайтовий скриптинг).
  • Secure: cookie передається лише через HTTPS-з'єднання, що підвищує безпеку передачі даних.
  • SameSite: запобігає надсиланню cookie з крос-сайтовими запитами, допомагаючи захистити від CSRF-атак (крос-сайтове підроблення запитів).

ВИКОРИСТАННЯ COOKIES

Cookies ідеально підходять для зберігання даних, які повинні передаватися на сервер з кожним запитом, наприклад, для автентифікації чи відстеження сесій.

Однак через обмеження на розмір і автоматичну передачу з кожним запитом, вони не завжди є найкращим вибором для зберігання великих обсягів даних або інформації, яка не потрібна серверу.

Основні сценарії використання:

  • зберігання сесійних ідентифікаторів;
  • збереження інформації про вхід до системи;
  • налаштування користувацьких переваг, які мають бути доступні серверу (наприклад, мовні налаштування).

На відміну від localStorage та sessionStorage, cookies продовжують залишатися популярним інструментом, особливо в сценаріях, де потрібен обмін даними із сервером на кожному етапі роботи програми.

CACHE API

Cache API — це сучасний інструмент для роботи з кешем на стороні клієнта, який дозволяє вебзастосункам зберігати HTTP-запити та відповіді в локальному сховищі.

Він використовується для створення прогресивних вебзастосунків (PWA), які можуть працювати офлайн або в умовах повільного інтернет-з'єднання, надаючи користувачам швидший доступ до закешованих ресурсів.

Cache API надає контроль над тим, які ресурси зберігати в кеші, що дає розробникам можливість керувати збереженням та оновленням статичних файлів (таких як HTML, CSS, JavaScript, зображення) та динамічних даних.

Особливості Cache API:

  • довготривале зберігання (закешовані ресурси залишаються доступними, навіть якщо інтернет-з'єднання відсутнє);
  • тонкий контроль (на відміну від традиційного HTTP-кешу, Cache API дозволяє вибирати, які ресурси зберігати, коли їх оновлювати і як ними керувати);
  • робота з Service Workers (Cache API часто використовується разом із Service Workers для створення програм, які працюють офлайн).

Приклад роботи з Cache API

Відкриття кешу й додавання ресурсу:

Cache API використовує проміси для роботи з асинхронними операціями, такими як додавання, отримання та видалення ресурсів.

// Відкриття (або створення) кешу з ім'ям 'my-cache'
`caches.open('my-cache').then(cache => {`
// Додавання ресурсів у кеш
`cache.addAll([
'/index.html',
'/styles.css',
'/script.js',
'/image.jpg'
]);
});`

У цьому прикладі створюється кеш з ім'ям my-cache, і до нього додаються кілька статичних ресурсів. Тепер ці файли будуть доступні в кеші, навіть якщо програма працює офлайн.

Отримання даних із кешу:

Для отримання даних із кешу використовується метод cache.match(), який перевіряє, чи є у кеші запит із відповідним URL.

// Отримання ресурсу з кешу
`caches.match('/index.html').then(response => {`
`if (response) {`
// Ресурс знайдено у кеші
`return response.text();
} else {`
// Ресурс відсутній у кеші
`console.log('Resource not found in cache');
}
});`

Якщо ресурс знайдено в кеші, він повертається, якщо ні, можна продовжити обробку запиту, відправивши його на сервер.

Видалення кешу:

Щоб підтримувати кеш в актуальному стані, необхідно час від часу видаляти застарілі версії кешу. Це можна зробити за допомогою методу caches.delete().

// Видалення кешу з ім'ям 'my-cache'
`caches.delete('my-cache').then(success => {
if (success) {
console.log('Cache deleted');
}
});`

Приклад використання Cache API із Service Workers:

Часто Cache API використовується разом із Service Workers для створення offline-first додатків.

Service Worker — це фоновий скрипт, який може перехоплювати мережні запити й обслуговувати їх із кешу чи мережі залежно від доступності.

Приклад базового Service Worker за допомогою Cache API:

`self.addEventListener('install', event => {`
// Відкриття кешу та додавання ресурсів при встановленні Service Worker
`event.waitUntil(
caches.open('my-cache').then(cache => {
return cache.addAll([
'/index.html',
'/styles.css',
'/script.js',
'/image.jpg'
]);
})
);
});`
`self.addEventListener('fetch', event => {`
// Перехоплення мережевих запитів та обслуговування їх із кешу, якщо вони там є
`event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
}); `

Цей Service Worker спочатку кешує ресурси при встановленні, а потім перехоплює всі мережеві запити, перевіряючи наявність ресурсу, що запитується в кеші. Якщо ресурс знайдено, він повертається з кешу, інакше запит надсилається на сервер.

ВИКОРИСТАННЯ CACHE API

Cache API ідеально підходить для програм, які повинні працювати в умовах обмеженого або відсутнього інтернет-з'єднання. Це особливо важливо для мобільних користувачів, які можуть мати нестабільні з'єднання.

Використання Cache API допомагає поліпшити продуктивність програм завдяки швидкому доступу до закешованих даних і знижує навантаження на сервер, оскільки користувачі можуть повторно використовувати збережені ресурси.

Основні сценарії використання:

  • прогресивні вебзастосунки (PWA) з можливістю офлайн-роботи;
  • кешування статичних ресурсів (наприклад, зображень, стилів, скриптів);
  • поліпшення продуктивності з допомогою зменшення кількості запитів до сервера.

Cache API є потужним інструментом для створення продуктивних і доступних програм, які можуть працювати навіть без підключення до мережі.

INDEXEDDB

IndexedDB — це потужне сховище даних на стороні клієнта, яке дозволяє зберігати великі обсяги структурованих даних, таких як об'єкти й масиви.

На відміну від localStorage, воно підтримує асинхронні операції та складні запити, такі як пошук за індексами й сортування.

Особливості IndexedDB:

  • підтримка складних даних (зберігання об'єктів, масивів та інших структур);
  • великий обсяг (підходить для зберігання значних даних (наприклад, медіаконтент);
  • асинхронність (операції не блокують інтерфейс користувача);
  • транзакції (всі дії відбуваються у рамках транзакцій, що гарантує цілісність даних).

Приклад роботи з IndexedDB:

Для початку створюється база даних та сховище об'єктів:

`const request = indexedDB.open('myDatabase', 1);
request.onupgradeneeded = event => {
const db = event.target.result;
db.createObjectStore('users', { keyPath: 'id' });
};`

Додавання даних відбувається через транзакції:

`const transaction = db.transaction(['users'], 'readwrite');
const objectStore = transaction.objectStore('users');
objectStore.add({ id: 1, name: 'John Doe' });`

ВИКОРИСТАННЯ INDEXEDDB

Використовуйте IndexedDB, якщо потрібно зберігати великі обсяги даних або працювати зі складнішими структурами. Це особливо корисно для офлайн-додатків і складних вебсистем з вимогами до продуктивності та кешування даних.

WEB SQL (ЗАСТАРІЛА ТЕХНОЛОГІЯ)

Web SQL — це технологія для роботи з базою даних на стороні клієнта, яка дозволяла вебдодаткам взаємодіяти з реляційною базою даних, використовуючи мову SQL.

Однак її було визнано застарілою і більше не розвивається. Основна причина — недостатня крос-браузерна підтримка й відсутність стандартизації. Зараз Web SQL підтримується тільки в деяких браузерах, таких як Chrome та Safari, але не Firefox або Edge.

Чому Web SQL більше не використовується?

  • Відсутність стандартизації

Специфікація Web SQL була відхилена на користь інших технологій, таких як IndexedDB, які пропонують більшу гнучкість і не прив'язані до реляційних моделей.

  • Обмежена підтримка браузерами

Сучасні браузери не підтримують Web SQL або роблять це в обмеженому режимі.

  • Альтернативи

IndexedDB став кращим варіантом для роботи з даними на стороні клієнта, оскільки він більш гнучкий, безпечний і підтримує складні операції з даними.

Приклад роботи з Web SQL:

Для створення бази даних Web SQL використовувався наступний синтаксис:

`const db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS users (id unique, name)');
tx.executeSql('INSERT INTO users (id, name) VALUES (1, "John Doe")');
});`

Цей код відкриває або створює базу даних і дозволяє виконувати SQL запити, такі як створення таблиць і вставка даних.

Хоча Web SQL був корисним інструментом для роботи з реляційними даними, його використання в нових проєктах не рекомендується через обмежену підтримку й відсутність стандартизації. Сучасні вебпрограми воліють використовувати IndexedDB для роботи з клієнтськими даними.

ВИСНОВОК

Кожен тип клієнтського сховища має своє оптимальне застосування. Для короткотривалих і невеликих даних ідеальними є sessionStorage та localStorage, тоді як для обробки великих обсягів інформації або забезпечення офлайн-режиму краще підходять IndexedDB і Cache API.

Cookies залишаються незамінними для завдань, що вимагають передачі даних між клієнтом і сервером, наприклад, для автентифікації. Натомість Web SQL, як застаріла технологія, вже не рекомендується для використання через низьку крос-браузерну підтримку.

Вибір сховища повинен базуватися на потребах конкретного додатка: обсягу даних, складності їх структури, вимог до продуктивності й безпеки. Не бійтеся експериментувати з різними інструментами, комбінувати їх і шукати оптимальні рішення.

Не бійтеся пробувати різні варіанти, адаптувати їх до потреб ваших проєктів і тестувати. Кожна задача унікальна, й саме досвід допоможе знайти найкраще рішення. Експериментуйте, навчайтесь і створюйте програми, які радують вас та ваших користувачів.

Рекомендуємо публікації по темі