Хранение данных в браузере

Браузер даёт кучу инструментов, чтобы хранить данные. Какой выбрать, чтобы в итоге не забивать гвозди микроскопом?

Время чтения: 5 мин

При разработке современных веб-сайтов достаточно часто необходимо сохранять данные на стороне клиента. Для таких целей в браузере существует несколько разных способов, которые появились в разное время и отличаются друг от друга.

Cookie

Скопировано

Первый способ — это хранение данных в cookie. Этот способ — не просто хранилище данных в браузере. Данные, хранящиеся в куках, также передаются на сервер в виде HTTP-заголовка и могут быть им изменены. Cookie являются частью спецификации протокола HTTP, и их поддерживают все браузеры.

У хранения данных в Cookie есть много ограничений. Они передаются при каждом запросе к серверу, их размер ограничен 4096 байтами, а содержимое должно быть закодировано и быть безопасным, чтобы не сломать отправляемый запрос. Cookie не являются постоянным хранилищем, срок хранения данных по умолчанию ограничен длинной сессии, и для продления хранения кук используется дополнительный параметр.

Cookie имеют не самый удобный интерфейс чтения и записи, поэтому в работе многие разработчики чаще используют сторонние библиотеки, а не взаимодействуют с интерфейсом напрямую.

Как правило, этим способом пользуются для хранения авторизационных данных или когда доступ к записанным данным нужен на сервере. Ещё куки используются для отслеживания поведения пользователя на сайте, но браузеры активно с этим борются.

Web Storage

Скопировано

Web Storage – это интерфейс взаимодействия с хранилищем. Есть две реализации этого API: Local Storage и Session Storage. Оба способа имеют идентичный API и ограничения, а основным различием является время хранения данных.

Session Storage похож на краткосрочные Cookie, потому что данные в этом хранилище хранятся только во время жизни текущей сессии.

Local Storage, в теории, является бессрочным хранилищем данных. Хотя данные и должны храниться бессрочно, браузеры все равно вводят свои ограничения.

Так, например, при переполнении хранилища оно полностью очищается. А Safari очищает Local Storage если к нему не обращались в течение семи дней. То есть если пользователь не посещал ваш сайт больше 7 дней, то данные хранящиеся в нем будут удалены.

Максимальный объем хранимых данных — 5 Мб. При этом любой скрипт, загруженный на странице, может иметь доступ к Web Storage на этой странице. Поэтому не стоит хранить там приватную информацию или токены авторизации, так как таким скриптом может являться вредное браузерное расширение, которое ворует информацию пользователя.

Интерфейс взаимодействия с этим видом хранилища очень простой и достаточно удобный. Данные хранятся в виде ключ-значение, и функции названы интуитивно понятно.

        
          
          // Запись в полеwindow.localStorage.setItem('name', 'value')window.sessionStorage.setItem('name', 'value')// Чтение из поляconst nameFromLocalStorage = window.localStorage.getItem('name')const nameFromSessionStorage = window.sessionStorage.getItem('name')// Удаление поляwindow.localStorage.removeItem('name')window.sessionStorage.removeItem('name')// Очистка хранилищаwindow.localStorage.clear()window.sessionStorage.clear()
          // Запись в поле
window.localStorage.setItem('name', 'value')
window.sessionStorage.setItem('name', 'value')

// Чтение из поля
const nameFromLocalStorage = window.localStorage.getItem('name')
const nameFromSessionStorage = window.sessionStorage.getItem('name')

// Удаление поля
window.localStorage.removeItem('name')
window.sessionStorage.removeItem('name')

// Очистка хранилища
window.localStorage.clear()
window.sessionStorage.clear()

        
        
          
        
      

Можно заметить, что данные записываются в виде строк, поэтому если вы хотите сохранить сложную структуру, то сначала нужно сделать из неё строку с помощью JSON.stringify() и только после этого записывать.

Запись в Web Storage является синхронной. Это значит, что на время записи браузер не выполняет другие действия. Поэтому избегайте частых записей в этот вид хранилища.

Indexed DB

Скопировано

Это самый новый способ хранения данных. При этом он обладает достаточно сложным API. В отличие от всех остальных способов, это API асинхронное.

Данный способ представляет собой API базы данных, что зачастую излишне для веб-приложений. Существует много разных библиотек, упрощающих работу с этим видом хранилища.

Пример простого взаимодействия с Indexed DB:

        
          
          let dbconst connection = indexedDB.open('myDatabase', 1)connection.onupgradeneeded = function(event) {  db = event.target.result  db.createObjectStore('notes', {autoIncrement: true})}connection.onsuccess = function(event) {  db = event.target.result  addNote(db, 'Прочитать статью "Хранение данных в браузере"')}connection.onerror = function(event) {  console.log(`Ошибка при открытии базы данных: ${event.target.errorCode}`)}function addNote(db, text) {  const tx = db.transaction(['notes'], 'readwrite')  const store = tx.objectStore('notes')  const note = { text, timestamp: Date.now() }  tx.oncomplete = () => {    console.log('Заметка сохранена')  }  tx.onerror = (event) => {    console.log(`Ошибка при записи заметки: ${event.target.errorCode}`)  }  store.add(note)}
          let db
const connection = indexedDB.open('myDatabase', 1)

connection.onupgradeneeded = function(event) {
  db = event.target.result
  db.createObjectStore('notes', {autoIncrement: true})
}

connection.onsuccess = function(event) {
  db = event.target.result
  addNote(db, 'Прочитать статью "Хранение данных в браузере"')
}

connection.onerror = function(event) {
  console.log(`Ошибка при открытии базы данных: ${event.target.errorCode}`)
}

function addNote(db, text) {
  const tx = db.transaction(['notes'], 'readwrite')
  const store = tx.objectStore('notes')
  const note = { text, timestamp: Date.now() }

  tx.oncomplete = () => {
    console.log('Заметка сохранена')
  }
  tx.onerror = (event) => {
    console.log(`Ошибка при записи заметки: ${event.target.errorCode}`)
  }

  store.add(note)
}

        
        
          
        
      

Универсальные решения

Скопировано

Существуют универсальные решения, которые автоматически используют наиболее подходящий способ хранения данных в браузере. Одним из самых удобных решений является библиотека localForage. Она удачна тем, что очень похожа на полифил и не предоставляет возможности записи в какое-то конкретное хранилище, а сама выбирает, куда записывать данные в зависимости от поддержки браузера. По умолчанию она использует IndexedDB, а если оно не поддерживается, то localStorage.

API библиотеки практически идентично Web Storage. Основное его отличие в том, что все методы являются асинхронными.