Что такое sessionStorage?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое sessionStorage
SessionStorage — это встроенный механизм браузера для хранения данных на клиенте. За 10+ лет работы с фронтендом я часто встречаюсь с sessionStorage при тестировании и должен хорошо его понимать.
Определение
SessionStorage — это Web Storage API, который сохраняет данные в браузере на время сессии пользователя (пока вкладка открыта).
Как работает
Синтаксис JavaScript
// Сохранить данные
sessionStorage.setItem('key', 'value')
sessionStorage.setItem('user_id', '123')
sessionStorage.setItem('preferences', JSON.stringify({theme: 'dark'}))
// Получить данные
const value = sessionStorage.getItem('key')
const userId = sessionStorage.getItem('user_id')
// Удалить данные
sessionStorage.removeItem('key')
// Очистить всё
sessionStorage.clear()
// Получить количество items
const length = sessionStorage.length
SessionStorage vs LocalStorage vs Cookies
| Параметр | SessionStorage | LocalStorage | Cookies |
|---|---|---|---|
| Время жизни | До закрытия вкладки | До явного удаления (годы) | До истечения (или явно) |
| Объем | ~5-10 MB | ~5-10 MB | ~4 KB |
| Доступ | JS только | JS только | JS + Server |
| HTTPS | Да | Да | Да (если Secure flag) |
| Domain | Вкладка только | Все вкладки одного домена | Все вкладки + Server |
| Автоотправка | Нет | Нет | Да (с каждым request) |
SessionStorage vs LocalStorage
SessionStorage
Время жизни: Пока открыта вкладка/окно браузера
Когда использовать:
- Временные данные
- Form state во время заполнения
- Cart до checkout
- User preferences на время сессии
- UI state (открыта ли боковая панель)
Пример:
// User заполняет multi-step форму
// Шаг 1: Сохранить в sessionStorage
sessionStorage.setItem('form_step_1', JSON.stringify({name: 'John', email: 'john@example.com'}))
// Шаг 2: Получить из sessionStorage и добавить новые данные
const step1 = JSON.parse(sessionStorage.getItem('form_step_1'))
const step2 = {address: '123 Main St', city: 'NYC'}
sessionStorage.setItem('form_data', JSON.stringify({...step1, ...step2}))
// После submit → clear
sessionStorage.clear()
LocalStorage
Время жизни: Постоянно (до явного удаления)
Когда использовать:
- User preferences (theme, language)
- User ID для repeat visits
- Cached data
- Offline-first приложения
Пример:
// User выбирает тему
localStorage.setItem('theme', 'dark')
// При следующем визите:
const theme = localStorage.getItem('theme') || 'light'
applyTheme(theme)
// Удалить только при logout
localStorage.removeItem('theme')
Практический пример sessionStorage
Сценарий: Multi-tab checkout
// Tab 1: User добавляет items в cart
sessionStorage.setItem('cart', JSON.stringify([
{id: 1, name: 'Product A', qty: 2},
{id: 2, name: 'Product B', qty: 1}
]))
// Tab 1: User открывает новую вкладку
// Tab 2: sessionStorage.getItem('cart') → null
// Почему? Потому что sessionStorage отдельный для каждой вкладки!
// Если нужны данные между вкладками → используй localStorage
Безопасность sessionStorage
Чего НЕ нужно хранить
// ❌ НИКОГДА не сохраняй sensitive data в sessionStorage
sessionStorage.setItem('password', 'myPassword123')
sessionStorage.setItem('credit_card', '4532-1234-5678-9010')
sessionStorage.setItem('api_key', 'sk_live_abc123xyz')
sessionStorage.setItem('access_token', token) // Иногда OK, но опасно
// Почему?
// 1. XSS атака: JavaScript injection может украсть данные
// 2. Visible в DevTools → видно при demo
// 3. Не encrypted
Правильное использование
// ✓ Безопасно хранить
sessionStorage.setItem('user_id', '123')
sessionStorage.setItem('username', 'john_doe')
sessionStorage.setItem('theme', 'dark')
sessionStorage.setItem('notification_unread_count', '5')
// Для sensitive: используй httpOnly cookies (server отправляет)
// Браузер автоматически отправляет с каждым запросом
// JavaScript не может прочитать (protected от XSS)
SessionStorage при тестировании
Что я проверяю в Cypress
describe('SessionStorage functionality', () => {
it('should save form data to sessionStorage', () => {
cy.visit('/form')
cy.get('[data-testid="name"]').type('John')
cy.get('[data-testid="email"]').type('john@example.com')
// Check sessionStorage
cy.window().then(win => {
const formData = win.sessionStorage.getItem('form')
expect(formData).to.include('John')
expect(formData).to.include('john@example.com')
})
})
it('should restore form data from sessionStorage', () => {
cy.visit('/form')
cy.window().then(win => {
win.sessionStorage.setItem('form', JSON.stringify({
name: 'Jane',
email: 'jane@example.com'
}))
})
cy.reload() // Перезагрузить страницу
cy.get('[data-testid="name"]').should('have.value', 'Jane')
cy.get('[data-testid="email"]').should('have.value', 'jane@example.com')
})
it('should clear sessionStorage on logout', () => {
// Setup: fill sessionStorage
cy.window().then(win => {
win.sessionStorage.setItem('user_data', 'sensitive')
})
// Logout
cy.get('[data-testid="logout"]').click()
// Verify cleared
cy.window().then(win => {
expect(win.sessionStorage.length).to.equal(0)
})
})
it('should NOT persist sessionStorage across tabs', () => {
cy.window().then(win => {
win.sessionStorage.setItem('tab_specific', 'data')
})
// Open new tab
cy.window().then(win => {
cy.visit('/') // Same URL в новом окне
})
// This would be in different tab/window
// sessionStorage will be empty
})
})
Chrome DevTools при тестировании
1. Open DevTools (F12)
2. Go to Application tab
3. Left sidebar → Storage → Session Storage
4. Select domain
5. See all key-value pairs
6. Can edit/delete values
Это очень полезно для debugging
Типичные use cases
1. Multi-step форма
// Step 1: Personal info
function saveStep1() {
sessionStorage.setItem('step1', JSON.stringify({
firstName: 'John',
lastName: 'Doe'
}))
}
// Step 2: Address
function saveStep2() {
sessionStorage.setItem('step2', JSON.stringify({
street: '123 Main St',
city: 'NYC'
}))
}
// Final: Combine and submit
function submit() {
const step1 = JSON.parse(sessionStorage.getItem('step1'))
const step2 = JSON.parse(sessionStorage.getItem('step2'))
const fullData = {...step1, ...step2}
// POST to server
fetch('/api/submit', {method: 'POST', body: JSON.stringify(fullData)})
// Clear after success
sessionStorage.clear()
}
2. Shopping cart (temporary)
function addToCart(product) {
let cart = JSON.parse(sessionStorage.getItem('cart')) || []
cart.push(product)
sessionStorage.setItem('cart', JSON.stringify(cart))
}
function getCartCount() {
const cart = JSON.parse(sessionStorage.getItem('cart')) || []
return cart.length
}
function checkout() {
const cart = JSON.parse(sessionStorage.getItem('cart'))
// Submit order
// ...
// Clear cart
sessionStorage.removeItem('cart')
}
3. UI state preservation
// User expands filter section
function toggleFilter() {
const isExpanded = sessionStorage.getItem('filter_expanded') === 'true'
if (isExpanded) {
sessionStorage.setItem('filter_expanded', 'false')
collapseFilter()
} else {
sessionStorage.setItem('filter_expanded', 'true')
expandFilter()
}
}
// On page reload, restore state
window.addEventListener('load', () => {
if (sessionStorage.getItem('filter_expanded') === 'true') {
expandFilter()
}
})
Важные ограничения
1. Размер
~5-10 MB per domain
Что тестировать:
✓ Добавить 100 MB данных → должна быть ошибка
✓ Graceful handling: show error, не crash приложение
2. Только строки
// sessionStorage хранит только strings!
sessionStorage.setItem('number', 42)
const value = sessionStorage.getItem('number')
console.log(typeof value) // 'string', не number!
console.log(value === '42') // true
// Правильно: JSON stringify для objects
sessionStorage.setItem('user', JSON.stringify({id: 1, name: 'John'}))
const user = JSON.parse(sessionStorage.getItem('user'))
3. Синхронный (может быть медленным)
// sessionStorage операции блокируют
sessionStorage.setItem('large_data', hugeDatabaseOfMillionRecords) // Может заморозить UI
// Лучше:
setTimeout(() => {
sessionStorage.setItem('large_data', data)
}, 0) // Async-like behavior
Блокировка sessionStorage
Создана ещё некоторая информация при тестировании:
Private browsing
В режиме инкогнито большинства браузеров sessionStorage может быть limited
Что тестировать:
✓ Private mode: sessionStorage работает или нет?
✓ Graceful handling если недоступен
Отключено
// User может отключить sessionStorage
try {
sessionStorage.setItem('test', 'test')
} catch (e) {
console.log('sessionStorage недоступен')
// Fallback to memory, cookies, etc
}
SessionStorage в PWA (Progressive Web Apps)
// Service Worker может сохранять в sessionStorage
// Useful для offline-first apps
// На основе Service Worker:
sessionStorage.setItem('offline_queue', JSON.stringify([
{action: 'POST', url: '/api/post', data: {...}},
{action: 'DELETE', url: '/api/item/123'}
]))
// Когда вернётся online:
const queue = JSON.parse(sessionStorage.getItem('offline_queue'))
queue.forEach(item => {
fetch(item.url, {method: item.action, body: item.data})
})
sessionStorage.removeItem('offline_queue')
Тестирование edge cases
test('should handle sessionStorage quota exceeded', () => {
try {
// Try to fill sessionStorage
for (let i = 0; i < 1000000; i++) {
sessionStorage.setItem(`key_${i}`, 'x'.repeat(1000))
}
} catch (e) {
// Should catch QuotaExceededError
expect(e.name).to.equal('QuotaExceededError')
// App should gracefully handle
}
})
test('should handle JSON parse errors', () => {
sessionStorage.setItem('corrupted', 'not valid json')
try {
const data = JSON.parse(sessionStorage.getItem('corrupted'))
} catch (e) {
expect(e instanceof SyntaxError).to.be.true
// App should handle gracefully
}
})
Заключение
SessionStorage — это полезный инструмент для хранения временных данных на клиенте.
Когда использовать:
- Form state во время заполнения
- Временные UI state
- Cart до checkout
- Session-specific data
Когда НЕ использовать:
- Sensitive data (passwords, tokens)
- Persistent data (user preferences)
- Data между вкладками (используй localStorage или cookies)
При тестировании проверяю:
- Данные сохраняются и восстанавливаются
- Очищаются при logout
- Не ломаются при quota exceeded
- Graceful fallback если недоступен
- Нет sensitive data утечек
Понимание sessionStorage важно для QA, потому что это часто используется в современных веб-приложениях и нужно проверять правильность работы.