Веб-приложения в нашем мире становятся всё более и более интерактивными и сложными, что требует хранения данных не только на сервере, но и на клиентской стороне.
Для этого браузеры предоставляют разработчикам множество инструментов для локального хранения данных, помогающих улучшить производительность и опыт пользователя.
Локальные хранилища позволяют программам хранить данные прямо в браузере пользователя, что избавляет от необходимости постоянно обращаться к серверу. Это особенно полезно в случаях, когда приложение должно работать в автономном режиме или в условиях нестабильного интернет-соединения.
В этой статье мы рассмотрим основные типы хранилищ на фронтенде, такие как sessionStorage, localStorage, cookies, Cache API, IndexedDB и WebSQL.
Мы объясним когда и как их использовать, а также приведём примеры кода для каждого из них. Понимание этих инструментов поможет вам эффективно работать с данными, создавать более быстрые, устойчивые и удобные для пользователя программы.
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, как устаревшая технология, уже не рекомендуется для использования из-за низкой кросс-браузерной поддержки.
Выбор хранилища должен базироваться на потребностях конкретного приложения: объёма данных, сложности их структуры, требований к производительности и безопасности. Не бойтесь экспериментировать с разными инструментами, комбинировать их и искать оптимальные решения.
Не бойтесь пробовать разные варианты, адаптировать их к потребностям ваших проектов и тестировать. Каждая задача уникальна, и сам опыт поможет найти лучшее решение. Экспериментируйте, обучайтесь и создавайте программы, которые радуют вас и ваших пользователей.