Кратко
СкопированоЭто объект, хранящийся в window, который позволяет долговременно сохранять данные в браузере. Работает как хранилище данных в формате ключ-значение — при сохранении данных мы указываем имя поля, в которое должны быть сохранены данные, и затем используем это имя для их получения.
Значения хранятся в виде строк. При попытке сохранения других типов данных, они будут приведены к строке. Например, если записать число, то при чтении нам вернётся число, записанное в строку.
Не имеет ограничений по времени хранения, может быть очищен пользователем вручную или браузером при переполнении автоматически (браузеры на основе движка WebKit, например Safari, очищают local, если к нему не обращались в течение 7 дней).
Максимальный объём данных ограничен размером 5MB.
Пример
СкопированоЗаписываем данные:
window.localStorage.setItem('name', 'Дока Дог')
window.localStorage.setItem('name', 'Дока Дог')
При чтении ранее записанных данных по ключу name мы получим Дока Дог:
const name = window.localStorage.getItem('name')console.log(name)// 'Дока Дог'
const name = window.localStorage.getItem('name')
console.log(name)
// 'Дока Дог'
Повторная запись по тому же ключу приведёт к замене данных:
window.localStorage.setItem('name', 'Собака Дока')const name = window.localStorage.getItem('name')console.log(name)// 'Собака Дока'
window.localStorage.setItem('name', 'Собака Дока')
const name = window.localStorage.getItem('name')
console.log(name)
// 'Собака Дока'
Как понять
СкопированоЕсли вам нужно сохранить данные в браузере на долгое время и объём этих данных достаточно большой, то local — то, что вам нужно. Данные будут храниться бессрочно и могут быть стёрты только в двух случаях: при превышении лимита по размеру данных или очистке хранилища пользователем или программно.
Как пишется
СкопированоЗапись
СкопированоДля записи используйте метод set. Он принимает два строковых параметра: ключ, по которому будет сохранено значение, и само значение.
window.localStorage.setItem('name', 'Дока Дог')
window.localStorage.setItem('name', 'Дока Дог')
Чтение
СкопированоЗа чтение отвечает get с одним параметром, который указывает на ключ для чтения и возвращает полученное значение из хранилища. Если по этому ключу нет значения, то метод вернёт null.
window.localStorage.getItem('name') // вернёт 'Дока Дог'window.localStorage.getItem('user') // вернёт `null`
window.localStorage.getItem('name') // вернёт 'Дока Дог'
window.localStorage.getItem('user') // вернёт `null`
Удаление
СкопированоУдаляет запись из хранилища remove. Он успешно выполнится, даже если указанного ключа не существует в хранилище.
window.localStorage.removeItem('name')window.localStorage.removeItem('user')
window.localStorage.removeItem('name')
window.localStorage.removeItem('user')
Очистка хранилища
СкопированоМетод clear очищает хранилище полностью.
window.localStorage.clear()
window.localStorage.clear()
Количество полей в хранилище
СкопированоИспользуя свойство length, можно узнать, сколько всего полей было записано в хранилище.
console.log(window.localStorage.length)// 0
console.log(window.localStorage.length)
// 0
Получение ключа по индексу
СкопированоМетод key получает ключ по индексу. Значения в хранилище хранятся в порядке их добавления, поэтому значение, добавленное первым, будет храниться в позиции 0 и так далее.
window.localStorage.setItem('name', 'Дока Дог')console.log(window.localStorage.key(0))// 'name'
window.localStorage.setItem('name', 'Дока Дог')
console.log(window.localStorage.key(0))
// 'name'
Таким образом, используя количество полей в хранилище и получение ключа по индексу, можно организовать перебор всех значений в хранилище.
const localStorageSize = window.localStorage.lengthfor (let i = 0; i < localStorageSize; i++) { console.log( window.localStorage.getItem(localStorage.key(i)) )}
const localStorageSize = window.localStorage.length
for (let i = 0; i < localStorageSize; i++) {
console.log(
window.localStorage.getItem(localStorage.key(i))
)
}
События
СкопированоПри установке значения в хранилище срабатывает глобальное событие storage, с помощью которого можно отслеживать изменения в хранилище.
💡 Событие происходит только на других открытых страницах текущего сайта.
Событие содержит свойства:
key— ключ, который был изменён (при вызове методаclearключ будет( ) null);old— старое значение, записанное в поле;Value new— новое значение, записанное в поле;Value url— адрес страницы, на которой вызвано изменение.
window.addEventListener('storage', function (evt) { console.log(evt)})
window.addEventListener('storage', function (evt) {
console.log(evt)
})
На практике
Скопированосоветует
Скопировано🛠 При помощи local можно сохранять данные, относящиеся к пользователю, не храня их на сервере. В следующем примере будем запоминать размер шрифта на сайте и восстанавливать размер из хранилища, если он был изменён до этого.
🛠 Можно использовать для синхронизации нескольких открытых в браузере вкладок. При изменении размера шрифта в одной вкладке мы узнаем об этом во всех остальных и тоже изменим размер.
function changePageFontSize(size) { document.style.fontSize = `${size}px`}window.addEventListener('storage', function (evt) { if (evt.key === 'pageFontSize') { changePageFontSize(evt.newValue) }})
function changePageFontSize(size) {
document.style.fontSize = `${size}px`
}
window.addEventListener('storage', function (evt) {
if (evt.key === 'pageFontSize') {
changePageFontSize(evt.newValue)
}
})
🛠 Иногда нам нужно сохранить не просто текст, а целую структуру данных. В этом нам поможет JSON.
const user = { name: 'Дока Дог', avatarUrl: 'mascot-doka.svg'}localStorage.setItem('user', JSON.stringify(user))
const user = {
name: 'Дока Дог',
avatarUrl: 'mascot-doka.svg'
}
localStorage.setItem('user', JSON.stringify(user))
И после чтения парсим:
function readUser() { const userJSON = localStorage.getItem('user') if (userJSON === null) { return undefined } // Если вдруг в хранилище оказался невалидный JSON, // предохраняемся от этого try { return JSON.parse(userJSON) } catch (e) { localStorage.removeItem('user') return undefined }}console.log(readUser())// {// name: 'Дока Дог',// avatarUrl: 'mascot-doka.svg'// }
function readUser() {
const userJSON = localStorage.getItem('user')
if (userJSON === null) {
return undefined
}
// Если вдруг в хранилище оказался невалидный JSON,
// предохраняемся от этого
try {
return JSON.parse(userJSON)
} catch (e) {
localStorage.removeItem('user')
return undefined
}
}
console.log(readUser())
// {
// name: 'Дока Дог',
// avatarUrl: 'mascot-doka.svg'
// }
🛠 Если ваш сайт использует скрипты аналитики или другие внешние библиотеки, то они также имеют доступ к хранилищу. Поэтому лучше именовать ключи для записи в хранилище с префиксом в едином стиле. Например, при записи чего-либо на таком сайте я бы выбрал префикс YD, тогда можно сгруппировать только нужные значения или отфильтровать их в инструментах разработчика.
🛠 Используйте функции-обёртки для предотвращения ошибок, связанных с неудачными попытками записи, отсутствием local в браузере и дублированием кода.
function getItem(key, value) { try { return window.localStorage.getItem(key) } catch (e) { console.log(e) }}function setItem(key, value) { try { return window.localStorage.setItem(key, value) } catch (e) { console.log(e) }}function setJSON(key, value) { try { const json = JSON.stringify(value) setItem(key, json) } catch (e) { console.error(e) }}function getJSON(key) { try { const json = getItem(key) return JSON.parse(json) } catch (e) { console.error(e) }}
function getItem(key, value) {
try {
return window.localStorage.getItem(key)
} catch (e) {
console.log(e)
}
}
function setItem(key, value) {
try {
return window.localStorage.setItem(key, value)
} catch (e) {
console.log(e)
}
}
function setJSON(key, value) {
try {
const json = JSON.stringify(value)
setItem(key, json)
} catch (e) {
console.error(e)
}
}
function getJSON(key) {
try {
const json = getItem(key)
return JSON.parse(json)
} catch (e) {
console.error(e)
}
}
советует
Скопировано🛠 Как предотвратить удаление данных из хранилища?
Когда и как происходит удаление данных? Как нам сохранить данные?
Вы можете использовать два способа хранения данных — «временный» и «постоянный». Во «временном» режиме браузер может удалить ваши данные, при условии, что этот процесс не помешает работе пользователя. В постоянном режиме этого не случится, даже в случае нехватки места. Однако в этом режиме пользователь может самостоятельно очищать хранилище.
По умолчанию все хранилища (local, , и т. д.) работают во временном режиме. Если сайт не запросил постоянное хранение данных — браузер может удалить его данные по своему усмотрению. Например, если на устройстве мало места.
🛠 Как выглядит процесс очистки?
При автоматической очистке места браузеры должны удалить наименее ценные для пользователя данные.
Браузеры на основе Chromium освобождают место последовательно, удаляя данные сайтов. Удаление начинается с сайтов, которые давно не посещались, и продолжается пока не освободится достаточно места.
Internet Explorer 10+ не очищает данные, но при этом не даёт записывать данные сверх лимита.
Firefox начинает очистку, когда заканчивается свободное место на диске. Порядок удаления определяется по тому же принципу, что и в браузерах на основе Chromium.
Safari раньше вообще не удалял данные, но сейчас использует семидневный лимит на хранение всех записываемых данных.
🛠 Как включить режим постоянного хранения данных?
Все необходимые методы для работы с браузерным хранилищем находятся в window. Нужный нам метод называется persist:
(async () => { // Пытается переключиться на «постоянный» режим хранения. // Возвращает true, если получилось. false, если нет. const persistModeEnabled = await window.navigator.storage?.persist()})()
(async () => {
// Пытается переключиться на «постоянный» режим хранения.
// Возвращает true, если получилось. false, если нет.
const persistModeEnabled = await window.navigator.storage?.persist()
})()
Можно усовершенствовать наш код, воспользовавшись методом persisted. Этот метод вернёт нам true, если хранилище уже переключено в постоянный режим.
Мы вызываем метод persisted и переключаем хранилище на постоянный режим, только если оно ещё не переключено:
(async () => { // boolean значение, указавающее на то, // включен ли «постоянный» режим хранения данных изначально const isAlreadyPersist = await window.navigator.storage?.persisted() if (isAlreadyPersist) { console.info('Хранилище уже переключено в постоянный режим хранения.') return } // boolean значение, указывающее на то, // удалось ли переключиться на «постоянный» режим хранения const persistModeEnabled = await window.navigator.storage?.persist() if (persistModeEnabled) { console.info('Браузер успешно сменил режим хранения на «постоянный».') return } console.info( 'Браузер столкнулся с проблемами при попытке смены режима. Возможно, вам стоит обновиться до последней версии либо использовать на сайте HTTPS-протокол.' )})()
(async () => {
// boolean значение, указавающее на то,
// включен ли «постоянный» режим хранения данных изначально
const isAlreadyPersist = await window.navigator.storage?.persisted()
if (isAlreadyPersist) {
console.info('Хранилище уже переключено в постоянный режим хранения.')
return
}
// boolean значение, указывающее на то,
// удалось ли переключиться на «постоянный» режим хранения
const persistModeEnabled = await window.navigator.storage?.persist()
if (persistModeEnabled) {
console.info('Браузер успешно сменил режим хранения на «постоянный».')
return
}
console.info(
'Браузер столкнулся с проблемами при попытке смены режима. Возможно,
вам стоит обновиться до последней версии либо использовать
на сайте HTTPS-протокол.'
)
})()