Усі три зберігають дані в браузері, але з різним терміном життя, обсягом і, головне, - різною поведінкою щодо сервера.
localStorage |
sessionStorage |
cookies | |
|---|---|---|---|
| живе | доки не видалять | доки відкрита вкладка | до Expires/Max-Age або до закриття браузера |
| видимість | усі вкладки домену | лише поточна вкладка | усі вкладки домену |
| обсяг | ~5 МБ на домен | ~5 МБ | ~4 КБ на cookie |
| іде на сервер | ні | ні | з кожним запитом |
| доступ з JS | так | так | так, якщо не HttpOnly |
Web Storage (localStorage, sessionStorage):
localStorage.setItem('theme', 'dark');
localStorage.getItem('theme'); // 'dark'
localStorage.removeItem('theme');
// лише рядки - об'єкти через JSON
localStorage.setItem('filters', JSON.stringify({ city: 'Київ' }));
const filters = JSON.parse(localStorage.getItem('filters') ?? '{}');
- зберігаються лише рядки:
setItem('count', 5)збереже'5'; - API синхронний - великі записи блокують головний потік;
- зміни в одній вкладці викликають подію
storageв інших вкладках того самого домену - спосіб синхронізувати вкладки; - у приватному режимі, при заповненому сховищі чи заблокованих cookies доступ може кидати виняток - звертання варто обгортати в
try.
Cookies створені для сервера: браузер автоматично додає їх до кожного запиту на домен. Тому в них зберігають ідентифікатор сесії, а не налаштування інтерфейсу - інакше кожен запит, включно з картинками, нестиме зайві байти.
Безпека - головне:
- не зберігайте токени автентифікації в
localStorage. Будь-який скрипт на сторінці (включно з XSS чи скомпрометованою бібліотекою) прочитає їх і відправить зловмиснику; - сесійна cookie з прапорцем
HttpOnlyнедоступна JavaScript взагалі - XSS не зможе її вкрасти. Так працює автентифікація Laravel (і Sanctum для SPA на тому ж домені); Secure- лише через HTTPS,SameSite- захист від підробки запитів з інших сайтів.
Що куди класти:
- тема, згорнуті панелі, чернетка форми -
localStorage; - стан майстра, що не повинен «перетікати» в іншу вкладку, -
sessionStorage; - сесія, автентифікація -
HttpOnly-cookie від сервера; - великі обсяги чи бінарні дані - IndexedDB (асинхронна база в браузері).