Способы хранения данных в браузере
Обновлено: 21.11.2024
Современные веб-приложения обрабатывают большие объемы данных на стороне клиента. Возможно, им даже потребуется возможность работать в автономном режиме. Эти требования во многом объясняют, почему хранение данных на стороне клиента жизненно важно для веб-приложений следующего поколения.
Файлы cookie предлагают только ограниченное пространство для хранения — максимум 4 КБ или 4096 байт, поэтому большие объемы данных приходилось разбивать на фрагменты размером с файл cookie и управлять ими явно и напрямую.
Это неприемлемый подход к распределению и управлению хранилищем. Очевидно, нужен был новый подход.
Не нужно много времени, чтобы печенье рассыпалось
Файлы cookie вместе с доступом к сценариям на стороне сервера, предоставляемым общим интерфейсом шлюза (CGI), позволяли запускать самые ранние веб-приложения. В конечном итоге это привело нас к превращению браузеров в универсальную платформу приложений.
Сегодня существует четыре основных метода хранения больших объемов клиентских данных: веб-SQL, IndexedDB, веб-хранилище и кэш приложений. В следующих разделах каждый метод рассматривается отдельно, а также исследуются основные аспекты их программирования и работы.
Веб-SQL: знакомое (но устаревшее?) создание базы данных, выполнение
Web SQL — это API для хранения данных в базе данных и их извлечения с помощью SQL. До недавнего времени Safari, Chrome и Opera поддерживали Web SQL поверх конкурирующего стандарта IndexedDB. Однако в 2010 году SQLite была единственной базой данных, которая работала с Web SQL, и W3C прекратил работу над этой спецификацией, сославшись на отсутствие реализации в качестве причины.
Тем не менее, Web SQL отлично работает, поэтому давайте рассмотрим пример кода.
Работа с базами данных Web SQL знакома всем, кто работал с реляционными базами данных и SQL. Первым шагом в использовании базы данных является ее создание и открытие. Если вы не хотите специально создавать базу данных, вы можете просто начать использовать базу данных, и API создаст ее для вас.
Вот код для создания базы данных:
var db = openDatabase('кошки', '1.0',
Слева направо: openDatabase принимает следующие параметры: имя базы данных, номер версии, текстовое описание и предполагаемый размер базы данных.
После того как вы создали базу данных, вы можете приступить к ее использованию. Выполнение SQL в базе данных WebSQL так же просто, как создание объекта транзакции и последующее его выполнение:
tx.executeSql('СОЗДАТЬ ТАБЛИЦУ кошек (уникальный идентификатор, имя)');
tx.executeSql('ВСТАВИТЬ В ЗНАЧЕНИЯ котов (id,name) (1, "Мистер Джонс")');
Хотя Safari, Chrome, Opera и Mobile Safari по-прежнему поддерживают этот API, с 2010 года в Web SQL не произошло ничего нового, поэтому маловероятно, что он станет стандартом для локального хранилища.
Веб-хранилище: преимущества файлов cookie без раздувания
- Веб-хранилище является постоянным. Сохраненное значение не исчезает и не истечет, пока оно не будет явно удалено приложением или пользователем.
- Веб-хранилище может обрабатывать большие объемы данных. Текущие браузеры ограничивают общий размер области хранения до 5 МБ.
- Веб-хранилище не зависит от сервера и не отправляет данные на сервер. Конечно, вы можете хранить данные локально и синхронизировать их с сервером асинхронно, но веб-хранилище работает так же хорошо и так же полезно в автономном режиме, как и в сети.
- Веб-хранилище предоставляет четыре основных метода: getItem(key); УстановитьЭлемент (ключ, значение); удалитьЭлемент (ключ); и очистить().
Наконец, веб-хранилище включает два разных типа хранилища: SessionStorage и LocalStorage.
SessionStorage ограничивает объем данных, сохраняемых в текущем окне браузера, только этим окном браузера. Например, при использовании с приложением электронной коммерции использование sessionStorage для записи содержимого корзины покупок пользователя исключает вероятность случайных двойных покупок.
Тем временем LocalStorage сохраняется в окнах и на вкладках одного браузера. Таким образом, если у вас один и тот же сайт открыт в трех окнах Chrome, все они могут использовать один и тот же контейнер localStorage. Если у вас открыто три разных сайта на разных доменах, каждому нужен свой контейнер. Аналогичным образом, если один и тот же сайт открыт в разных браузерах, каждому браузеру нужен свой контейнер, поскольку они не имеют общего контекста выполнения.
Чтобы установить новую пару "ключ-значение", а затем получить ее, можно использовать следующий код JavaScript:
//сначала устанавливаем имя равным Sparky.
localStorage.setItem("имя", "Спарки");
//далее получаем значение firstname (подсказка, это будет Sparky).
IndexedDB: с возможностью поиска и без ограничений по размеру файла
API IndexedDB, как и веб-хранилище, этим летом сделал большой шаг вперед в процессе разработки веб-стандартов, став кандидатом в рекомендации W3C в июле 2013 г.
IndexedDB предлагает четыре конкретных преимущества по сравнению с веб-хранилищем:
- Поиск в проиндексированных данных может быть эффективным.
- Базы данных позволяют хранить несколько значений в качестве ключа, тогда как для данных "ключ-значение" требуется, чтобы каждый ключ был уникальным.
- Транзакционные базы данных обеспечивают некоторую защиту от сбоев системы и приложений. Если транзакция не завершилась успешно, ее можно отменить.
- Базы данных IndexedDB не имеют ограничений по размеру. В Firefox браузер запросит разрешение на расширение базы данных за пределы 50 МБ, но это не предел (фактически пределом является объем или диск) для хранения данных в IndexedDB.
В настоящее время все основные браузеры, кроме Safari, поддерживают IndexedDB. Однако, поскольку Safari поддерживает веб-SQL, можно использовать полифилл IndexedDB (называемый оболочкой), который реализует функции и синтаксис IndexedDB с помощью веб-SQL.
Первым шагом в использовании IndexedDB является открытие базы данных.
var request = indexedDB.open("myDatabase");
После того как вы создали базу данных, вы можете создать хранилище объектов (которое очень похоже на таблицу) и добавить в него данные. Предположим, у нас есть следующие данные:
Затем мы можем создать хранилище данных и использовать его с помощью следующего кода. Обратите внимание на обработчик onupgradeneeded: этот метод вызывается, когда вам нужно изменить структуру вашей базы данных.
var db = event.target.result;
var objectStore = db.createObjectStore("клиенты", );
for (var i в customerData)
IndexedDB отлично справляется с поиском в больших наборах данных и может повысить производительность веб-приложений, по возможности перемещая структурированные данные на сторону клиента. Он приближается к статусу рекомендации W3C и может использоваться в любом браузере, хотя и с некоторыми различиями между реализациями и, как уже отмечалось, только с помощью полифилла в Safari.
Кэш приложения: реализация автономного хранилища на стороне клиента
Кэш приложения не похож на другие перечисленные здесь API-интерфейсы хранения данных на стороне клиента, но стоит упомянуть его, так как он является важным компонентом, обеспечивающим работу автономных веб-приложений на стороне клиента.
Кэш приложений использует манифест кэша. Это простой текстовый документ со списком ресурсов, которые должны и не должны быть кэшированы, чтобы указать браузеру загружать определенные файлы, сохранять их и использовать кэшированную версию, а не делать запрос на сервер. Все основные веб-браузеры поддерживают кэш приложений.
Чтобы использовать кэш приложения, сохраните текстовый файл с расширением .appcache в корне веб-сайта, содержащий файлы, которые вы хотите кэшировать. В зависимости от используемого вами веб-сервера вам может потребоваться создать настраиваемый тип MIME для файлов .appcache, чтобы убедиться, что они правильно отображаются в браузере и могут быть прочитаны как файлы кеша приложения.
Случаи хранения данных и управления ими в браузере включают:
- сохранение состояния клиентского приложения, например текущего экрана, введенных данных, пользовательских настроек и т. д.
- утилиты, которые имеют доступ к локальным данным или файлам и предъявляют строгие требования к конфиденциальности
- прогрессивные веб-приложения (PWA), работающие в автономном режиме
Вот десять вариантов хранения данных браузера:
В этой статье рассматриваются десять различных способов хранения данных в браузере, рассматриваются их ограничения, плюсы и минусы, а также наилучшее использование каждого метода.
Прежде чем мы рассмотрим варианты, краткое примечание о сохранении данных…
Сохранение данных
Как правило, данные, которые вы храните, будут:
- постоянный: он остается до тех пор, пока ваш код не решит его удалить, или
- изменчивая: сохраняется до завершения сеанса браузера, обычно когда пользователь закрывает вкладку.
Реальность более тонкая.
Постоянные данные могут быть заблокированы или удалены пользователем, операционной системой, браузером или подключаемыми модулями в любой момент. Браузер может принять решение об удалении старых или больших элементов по мере того, как он приближается к емкости, выделенной для этого типа хранилища.
Браузеры также записывают состояние страницы. Вы можете уйти с сайта и щелкнуть назад или закрыть и снова открыть вкладку; страница должна выглядеть идентично. Переменные и данные, считающиеся только сеансовыми, по-прежнему доступны.
1. Переменные JavaScript
метрика | комментарий |
---|---|
capacity | нет строгих ограничений, но при заполнении памяти может произойти замедление или сбой браузера |
скорость чтения/записи | самый быстрый вариант |
сохранение | плохое: данные стирается при обновлении браузера |
Сохранение состояния в переменных JavaScript — самый быстрый и простой вариант. Я уверен, что вам не нужен пример, но…
- прост в использовании
- быстро
- нет необходимости в сериализации или десериализации
- хрупкое: обновление или закрытие вкладки стирает все
- Сценарии сторонних производителей могут проверять или перезаписывать глобальные (оконные) значения
Вы уже используете переменные. Вы можете рассмотреть возможность постоянного сохранения состояния переменной при выгрузке страницы.
2. Хранилище узлов DOM
метрика | комментарий |
---|---|
capacity | без строгих ограничений, но не идеально подходит для большого количества данных |
read/ скорость записи | быстрая |
сохранение | плохая: данные могут быть стерты другими скриптами или обновление |
Большинство элементов DOM, как на странице, так и в памяти, могут хранить значения в именованных атрибутах. Безопаснее использовать имена атрибутов с префиксом data- :
- атрибут никогда не будет связан с функциональностью HTML
- вы можете получить доступ к значениям через свойство набора данных, а не через более длинные методы .setAttribute() и .getAttribute().
Значения хранятся в виде строк, поэтому может потребоваться сериализация и десериализация. Например:
- вы можете определить значения в JavaScript или HTML, например
- полезно для хранения состояния определенного компонента
- DOM работает быстро! (вопреки распространенному мнению)
- хрупкое: обновление или закрытие вкладки стирает все (если только значение не отображается сервером в HTML)
- только строки: требуется сериализация и десериализация
- больше DOM влияет на производительность
- сторонние скрипты могут проверять или перезаписывать значения
Хранение узлов DOM работает медленнее, чем переменные. Используйте его с осторожностью в ситуациях, когда целесообразно хранить состояние компонента в HTML.
3. Веб-хранилище ( localStorage и sessionStorage )
метрика | комментарий | ||||
---|---|---|---|---|---|
емкость | 5 МБ на домен | ||||
скорость чтения/записи | < td>синхронная работа: может быть медленной|||||
сохранение | данные остаются до очистки |
метрика | комментарий |
---|---|
вместимость | зависит от устройства. Не менее 1 ГБ, но может занимать до 60 % свободного места на диске |
скорость чтения/записи | высокая |
сохранение | данные остаются до очистки |
IndexedDB предлагает низкоуровневый API, аналогичный NoSQL, для хранения больших объемов данных. Магазин можно индексировать, обновлять с помощью транзакций и искать с помощью асинхронных методов.
API IndexedDB сложен и требует некоторой обработки событий. Следующая функция открывает соединение с базой данных при передаче имени, номера версии и дополнительной функции обновления (вызывается при изменении номера версии):
Следующий код подключается к базе данных myDB и инициализирует хранилище объектов todo (аналогично таблице SQL или коллекции MongoDB). Затем он определяет автоматически увеличивающийся ключ с именем id :
После того, как подключение к базе данных будет готово, вы можете добавить новые элементы данных в транзакцию:
И вы можете получить значения, например первый элемент:
- гибкое хранилище данных с самым большим пространством
- надежные транзакции, индексирование и параметры поиска
- хорошая поддержка браузеров
IndexedDB — лучший вариант для надежного хранения больших объемов данных, но вам понадобится библиотека-оболочка, такая как idb, Dexie.js или JsStore.
5. API кэширования
метрика | комментарий |
---|---|
вместимость | зависит от устройства, но Safari ограничивает размер каждого домена до 50 МБ |
читать /write speed | быстро |
сохранение | данные сохраняются до очистки или после двух недель в Safari |
Этот API обычно используется сервисными работниками для кэширования сетевых ответов для прогрессивных веб-приложений. Когда устройство отключается от сети, кэшированные ресурсы могут быть повторно сохранены, чтобы веб-приложение могло работать в автономном режиме.
Следующий код сохраняет сетевой ответ в кеше с именем myCache :
Аналогичная функция может извлекать элемент из кеша. В этом примере он возвращает основной текст ответа:
- сохраняет любой сетевой ответ
- может повысить производительность веб-приложения
- позволяет веб-приложению работать в автономном режиме
- современный API на основе Promise
- нецелесообразно для хранения состояния приложения
- возможно, менее полезен вне прогрессивных веб-приложений
- Apple плохо относится к PWA и Cache API.
Cache API — лучший вариант для хранения файлов и данных, полученных из сети. Вы могли бы вероятно использовать его для хранения состояния приложения, но он не предназначен для этой цели, и есть варианты получше.
5.5 Кэш приложений
AppCache был несуществующим предшественником Cache API. Это не то решение для хранения, которое вы ищете. Здесь нечего смотреть. Пожалуйста, продолжайте.
6. API доступа к файловой системе
метрика | комментарий | ||||
---|---|---|---|---|---|
емкость | зависит от оставшегося места на диске | ||||
скорость чтения/записи | зависит от файловой системы | ||||
сохранение | данные остаются до очистки |
метрика | комментарий | ||||
---|---|---|---|---|---|
емкость | зависит от оставшегося места на диске | ||||
скорость чтения/записи | неизвестно | ||||
сохранение | данные остаются до очистки |
метрика | комментарий |
---|---|
емкость | варьируется, но несколько мегабайт должны быть возможны |
скорость чтения/записи | быстро |
сохранение | данные сеанса сохраняются до закрытия вкладки |
Свойство window.name задает и получает имя контекста просмотра окна. Вы можете установить одно строковое значение, которое сохраняется между обновлениями браузера или ссылкой в другом месте и щелчком назад. Например:
Проверьте значение, используя:
- прост в использовании
- может использоваться только для данных сеанса
- только строки: требуется сериализация и десериализация
- страницы в других доменах могут читать, изменять или удалять данные (никогда не используйте их для конфиденциальной информации)
window.name никогда не предназначался для хранения данных. Это обман, и есть варианты получше.
10. WebSQL
метрика | комментарий | ||||
---|---|---|---|---|---|
емкость | 5 МБ на домен | ||||
скорость чтения/записи | < td>медленно|||||
сохранение | данные остаются до очистки |
Метод | Описание |
---|---|
setItem() | Добавить ключ/значение в LocalStorage |
getItem() | Получить значение из LocalStorage |
removeItem() | Удалить элемент по его ключу |
clear()< /td> | Удалить все элементы из LocalStorage |
key() | Получить ключ элемента из LocalStorage |
setItem()
Используйте функцию setItem() для сохранения элемента в LocalStorage. Эта функция принимает ключ в качестве первого аргумента и значение в качестве второго аргумента. Как упоминалось ранее, оба должны быть строками.
В консоли вашего браузера давайте добавим элемент в наше локальное хранилище:
получитьItem()
Используйте функцию getItem() для извлечения данных из LocalStorage. Эта функция принимает в качестве аргумента ключ, который использовался при сохранении данных.
В вашей консоли давайте извлечем и напечатаем значение, которое было сохранено ранее с помощью setItem() :
Ваша консоль должна вывести "JavaScript".
удалитьЭлемент()
Используйте функцию removeItem(), чтобы удалить один элемент из LocalStorage. Вам необходимо указать ключ элемента, который вы хотите удалить, в качестве аргумента.
Попробуйте это в своей консоли, чтобы удалить данные, сохраненные с помощью setItem():
Консоль выводит "null", так как getItem() возвращает null всякий раз, когда не может получить элемент.
очистить()
Чтобы удалить все данные, хранящиеся в LocalStorage, используйте функцию clear():
Функция key() позволяет нам получить ключ элемента, сохраненного в LocalStorage, по его индексу. Браузер создает целочисленный индекс для каждого элемента, добавленного в LocalStorage.
Поскольку мы не создаем этот индекс, мы не должны использовать его для прямого извлечения ключей. Однако мы можем использовать эту функцию, чтобы получить все ключи, хранящиеся в LocalStorage:
Используя свойство length LocalStorage, мы перебираем каждый созданный индекс, чтобы распечатать все ключи, которые мы сохранили в LocalStorage. Затем мы можем использовать эти ключи с getItem() для извлечения всех сохраненных данных.
Теперь, когда мы рассмотрели все функции управления данными в браузере пользователя, давайте рассмотрим особый случай сохранения сложных объектов вместо строковых данных.
Сохранение объектов в LocalStorage
Бесплатная электронная книга: Git Essentials
Ознакомьтесь с нашим практическим руководством по изучению Git, включающим передовые практики, общепринятые стандарты и памятку. Перестаньте гуглить команды Git и на самом деле изучите их!
LocalStorage может использовать только строки для своих ключей и значений. Если мы попытаемся сохранить любой другой тип данных, он преобразует его в строку перед сохранением. Это может привести к неожиданному поведению, когда мы хотим сохранить объекты JavaScript.
Давайте создадим объект пользователя в консоли браузера и сохраним его в LocalStorage:
Теперь setItem() преобразует объект человека в строку. Когда мы извлекаем человека следующим образом:
Консоль нашего браузера покажет следующее:
Преобразование объекта JavaScript в строку дает [object Object] . По общему признанию, возвращать строку, которая указывает только на то, что объект был сохранен, бесполезно.
Чтобы правильно хранить объекты JavaScript в LocalStorage, нам сначала нужно преобразовать наш объект в строку JSON.
Для этого мы используем встроенную функцию JSON.stringify(). Результирующая строка этой функции будет содержать все свойства нашего объекта JSON. Мы сохраняем вывод этой функции при использовании setItem() .
Давайте сохраним объект человека после его преобразования в строку:
Чтобы получить эти данные как объект, нам нужно сделать две вещи. Во-первых, нам нужно использовать getItem(), чтобы получить его из LocalStorage. Затем нам нужно преобразовать строку JSON в объект JavaScript.
Начнем с того, что возьмем элемент из LocalStorage:
Теперь преобразуйте строку LocalStorage в объект с помощью JSON.parse() и зарегистрируйте ее в консоли браузера:
Выполнение этого кода даст вам следующий результат:
Обратите внимание на разницу в цвете в консоли при первой регистрации строки и при регистрации объекта. Мы также регистрируем свойство name человека, чтобы гарантировать, что свойства объекта по-прежнему доступны.
Теперь, когда у нас есть стратегия расширения использования LocalStorage за пределы строк, давайте обсудим передовые методы его использования.
Когда использовать LocalStorage
LocalStorage обеспечивает базовое сохранение данных на вашем веб-сайте. Он обычно используется для хранения данных, которые пользователю было бы удобно видеть, даже если браузер был обновлен. Например, многие формы сохраняют введенные пользователем данные в LocalStorage до тех пор, пока они не будут отправлены.
Статические веб-сайты обычно используют LocalStorage для хранения пользовательских настроек, таких как тема пользовательского интерфейса. Без веб-сервера и базы данных для сохранения пользовательских настроек LocalStorage позволяет им продолжать использовать ваш веб-сайт со своими настройками.
Однако LocalStorage не следует использовать для больших объемов данных. Помимо ограничения в 5 МБ, которого может быть недостаточно для приложений, интенсивно использующих данные, большие объемы данных снижают производительность при использовании LocalStorage.
Все функции LocalStorage являются синхронными операциями. Поэтому, если вы сохраняете или извлекаете большой блок данных, JavaScript должен завершить эту операцию LocalStorage, прежде чем он сможет выполнить другой код.
Помните, что при сохранении больших объектов JSON увеличивается стоимость производительности. Функции JSON.stringify() и JSON.parse() также являются синхронными. Они будут блокировать выполнение JavaScript до тех пор, пока они не будут завершены.
Никогда не храните конфиденциальную информацию в LocalStorage. Сюда входят пароли, ключи API, токены аутентификации, такие как JWT, и финансовая информация, например номера кредитных карт, и многие другие.
Помните, что каждый файл JavaScript, загруженный в ваш домен, имеет доступ к LocalStorage.Если вредоносный код JavaScript добавлен вами или вашими зависимостями, они могут получить пользовательские данные или токены, которые вы используете для аутентификации с помощью API.
Всегда храните конфиденциальные данные на сервере.
Заключение
LocalStorage – это хранилище данных, доступное в браузерах. Данные хранятся в виде пар строк ключ/значение, и каждый домен имеет доступ к своему LocalStorage.
При сохранении объектов JavaScript обязательно правильно преобразуйте их в строку с помощью JSON.stringify() перед сохранением. По мере извлечения данных преобразуйте их в объект с помощью JSON.parse() .
При использовании LocalStorage избегайте обработки больших объемов данных, так как это может снизить производительность, поскольку его функции синхронны. Самое главное, убедитесь, что в LocalStorage не хранятся конфиденциальные данные пользователей или приложений.
В веб-хранилище веб-приложения могут хранить данные локально в браузере пользователя.
Веб-хранилище определяется по происхождению (по домену и протоколу). Все страницы из одного источника могут хранить и получать доступ к одним и тем же данным.
Поддержка браузера
Числа в таблице указывают на первую версию браузера, которая полностью поддерживает веб-хранилище.
API | |||||
---|---|---|---|---|---|
Веб-хранилище | 4.0 | 8.0 | 3.5 | 4.0 | 11.5 |
Объекты веб-хранилища HTML
Веб-хранилище HTML предоставляет два объекта для хранения данных на клиенте:
- window.localStorage — хранит данные без даты истечения срока действия
- window.sessionStorage — сохраняет данные за один сеанс (данные теряются при закрытии вкладки браузера)
Перед использованием веб-хранилища проверьте поддержку браузером localStorage и sessionStorage:
if (typeof(Storage) !== "undefined") <
// Код для localStorage/sessionStorage.
> else <
// Извините ! Нет поддержки веб-хранилища..
>
Объект localStorage
Объект localStorage хранит данные без даты истечения срока действия. Данные не будут удалены при закрытии браузера и будут доступны на следующий день, неделю или год.
Пример
// Получить
document.getElementById("result").innerHTML = localStorage.getItem("lastname");
- Создайте пару имя/значение localStorage с name="lastname" и value="Smith"
- Получить значение "lastname" и вставить его в элемент с помощью
Пример выше можно было бы написать так:
// Сохраняем
localStorage.lastname = "Smith";
// Извлекаем
document.getElementById("result").innerHTML = localStorage.lastname;
Синтаксис для удаления элемента localStorage "lastname" следующий:
Примечание. Пары имя/значение всегда хранятся в виде строк. Не забудьте преобразовать их в другой формат, когда это необходимо!
В следующем примере подсчитывается, сколько раз пользователь нажал кнопку. В этом коде строка значения преобразуется в число, чтобы можно было увеличить счетчик:
Пример
if (localStorage.clickcount) <
localStorage.clickcount = Number(localStorage.clickcount) + 1;
> else <
localStorage.clickcount = 1;
>
document.getElementById("result").innerHTML = "Вы нажали кнопку " +
localStorage .clickcount + " раз(а)";
Объект sessionStorage
Объект sessionStorage аналогичен объекту localStorage, за исключением того, что он хранит данные только для одного сеанса. Данные удаляются, когда пользователь закрывает определенную вкладку браузера.
В следующем примере подсчитывается, сколько раз пользователь нажимал кнопку в текущем сеансе:
Читайте также:
- Сделать снимок в After Effects, где он сохраняется
- Я новичок в разногласиях, как удалить
- Что такое компьютерные программы
- Какой значок на рабочем столе запускает программу Word
- Формат M4a, чем открыть на Android