Современные веб-браузеры поддерживают несколько способов хранения данных из веб-сайтов на компьютере пользователя, чтобы потом получать их, когда это необходимо. Это позволяет долгосрочно хранить данные, сохранять сайты или документы для использования без подключения к сети, сохранять пользовательские настройки для сайта и многое другое
Сайты можно разделить:
На статические - в них верстка и контент строго зафиксированы
Статические сайты полезны, если количество контента небольшое, и контент одинаков для каждого пользователя, однако плохи тем, что изменения в верстке приводят к изменению каждой страницы
На динамические - в них сервер генерирует свой контент на странице в зависимости от конкретного URL-адреса, пользователя, данных в базе данных и других условий
Серверный код сайта может не только возвращать HTML-фрагменты и файлы в ответе, а динамически создавать и возвращать другие типы файлов (например, текст, PDF, CSV) или даже данные (JSON, XML)
Совсем недавно стал популярен подход “одностраничных приложений”, где весь сайт написан с одним HTML-файлом, который динамически обновляется по мере необходимости
Большинство современных веб-сайтов являются динамическими - они хранят данные на сервере, используя базу данных, а затем запускают код на стороне сервера чтобы извлечь данные, вставить их в HTML-шаблоны и отправить сформированный HTML клиенту для отображения в браузере пользователя
Хранилище на стороне клиента работает по схожим принципам, но используется по-другому. Оно состоит из API, который позволяет хранить данные на клиенте, а затем извлекать их при необходимости, например:
Часто, хранилища на сторонах клиента и сервера используются совместно
С первых дней Интернета, использовали куки (cookies) для хранения информации, чтобы персонализировать пользовательский опыт на веб-сайтах - это самая ранняя форма хранилища на стороне клиента
Куки представляют небольшую порцию текстовых данных, хранящихся в браузере. Всякий раз при открытии страницы браузер соответствующего сайта пересылает сохранённые куки обратно веб-серверу через HTTP-заголовки:
// Создание куки
document.cookie = "username=Chris; max-age=3600; path=/";
// Чтение куки
console.log(document.cookie);
// Удаление куки
document.cookie = "username=Chris; max-age=0";
Как можно заметить, у куки есть время жизни. Также куки могут хранить 4 Кб данных
Современные браузеры имеют гораздо более простые и эффективные API для хранения данных на стороне клиента, чем при использовании куки:
Web Storage API обеспечивает очень простой синтаксис для хранения и извлечения данных, состоящих из пар ключ-значение, где значение - это строка
Это полезно, когда просто нужно сохранить некоторые простые данные, такие как имя пользователя, вошёл ли он в систему и тому подобное
IndexedDB API обеспечивает браузер полной базой данных для хранения сложных данных
Это может быть использовано для хранения полных наборов записей клиентов и даже до сложных типов данных, таких как аудио или видео файлы
Веб-хранилища предоставляет механизмы, при помощи которых браузеры могут безопасно хранить пары ключ-значение в более интуитивно понятной манере, чем куки. В качестве веб-хранилища может выступать один из двух вариантов имплементации механизма:
Локальное хранилище (Local Storage) хранит данные для конкретного домена (а точнее тройки - протокол, домен и порт) и даже в случае, если браузер закрыт
Обычно браузеры выделяют около 5–10 МБ для хранилища на один домен страницы, точный объём зависит от браузера
// Сохранить
localStorage.setItem("theme", "dark");
// Получить
const theme = localStorage.getItem("theme");
console.log(theme);
// Удалить ключ
localStorage.removeItem("theme");
// Очистить всё
localStorage.clear();
// Аналогично для сессионного хранилища
sessionStorage.setItem("token", "12345");
console.log(sessionStorage.getItem("token"));
Так же как и куки, объект локального хранилища будет одинаковый для всех открытых вкладок во всех окнах браузера в рамках одного домена, но только в пределах одного браузера. Важно подметить, что пароли и другую чувствительную информацию нельзя хранить в локальном хранилище
Помимо обычного хранения данных хранилища часто используют для того чтобы реализовывать общение между несколькими вкладками веб-приложения с помощью события StorageEvent (например, смена музыки во второй вкладке приводит к ее воспроизведению в первой):
window.addEventListener("storage", (event) => {
console.log("Изменение:", event.key);
console.log("Новое значение:", event.newValue);
});
Важно заметить, что событие не сработает в той вкладке, где было изменено хранилище
IndexedDB API (или IDB) - это полноценная база данных, доступная в браузере, в которой можно хранить сложные связанные данные, типы которых не ограничиваются простыми значениями, такими как строки или числа
Использование IndexedDB является более сложным. Перед тем как мы сможем добавлять или изменять какие-либо данные, нужно сначала открыть базу данных и создать хранилища (аналогичные таблицам в базе данных)
const request = indexedDB.open("MyDatabase", 1);
request.onupgradeneeded = function (event) {
const db = event.target.result;
db.createObjectStore("users", { keyPath: "id" });
};
request.onsuccess = function (event) {
const db = event.target.result;
const transaction = db.transaction("users", "readwrite");
const store = transaction.objectStore("users");
store.add({ id: 1, name: "Chris" });
};
Другие преимущества IndexedDB:
IndexedDB может хранить любые сериализуемые объекты напрямую
В хранилищах же сложные объекты можно хранить в виде JSON-объектов. JSON (JavaScript Object Notation) - формат обмена данными. Его синтаксис и типы схожи на те, что есть в JavaScript
JSON-объект представляет собой множество пар ключ-значение. Ключ в JSON-объекте всегда является строкой. Для работы с JSON внутри JavaScript существуют методы JSON.parse() и JSON.stringify(obj):
const user = {
name: "Chris",
age: 35
};
// Сохраняем
localStorage.setItem("user", JSON.stringify(user));
// Получаем
const savedUser = JSON.parse(localStorage.getItem("user"));
console.log(savedUser.name);