Зачем это спрашивают
Все три механизма хранят данные в браузере, и снаружи кажутся одинаковыми. Но у них разный срок жизни, разная область видимости и разное отношение к серверу. Из этих различий вытекают целые классы багов: корзина пропала после перезапуска браузера, пользователь остался залогинен после выхода, во второй вкладке видна старая версия данных.
Интервьюер хочет услышать не определения, а понимание: где лежат данные вашего приложения, кто их читает и что это значит для тест-кейсов. Вопрос про HttpOnly и Secure дополнительно проверяет, знакомы ли вы с базовой безопасностью веба.
Как построить сильный ответ
Начните с главного отличия, затем дайте сравнение по нескольким осям и закончите тем, как это влияет на тестирование.
Главное отличие
Cookie браузер сам прикладывает к каждому HTTP-запросу к своему домену в заголовке Cookie. Сервер устанавливает их заголовком Set-Cookie. localStorage и sessionStorage — хранилища только для JavaScript на странице: на сервер они ничего не отправляют, пока скрипт явно не положит значение в запрос, например в заголовок Authorization.
Сравнение
| cookie | localStorage | sessionStorage | |
|---|---|---|---|
| уходит на сервер | автоматически с каждым запросом | нет | нет |
| срок жизни | до Expires / Max-Age; без них — до конца сессии браузера |
пока не удалят | пока открыта вкладка |
| область | домен и путь | origin: схема + хост + порт | origin и конкретная вкладка |
| объём | около 4 КБ на одну cookie | несколько мегабайт на origin | несколько мегабайт на origin |
| доступ из JS | да, если нет HttpOnly | да | да |
Важные детали про sessionStorage: данные переживают перезагрузку страницы, но не закрытие вкладки, а две вкладки одного сайта имеют разные хранилища. localStorage, наоборот, общий для всех вкладок одного origin.
Флаги cookie
- HttpOnly — cookie недоступна через
document.cookie, её видит только браузер при отправке запросов. Защищает сессию от кражи через XSS. - Secure — cookie отправляется только по HTTPS.
- SameSite — управляет отправкой при запросах с других сайтов (
Strict,Lax,None), защищает от CSRF. - Domain и Path — на какие адреса cookie будет отправляться.
Что это меняет для тестов
Знание хранилища подсказывает проверки: перезагрузка, закрытие и открытие браузера, вторая вкладка, режим инкогнито, выход из аккаунта, ручное удаление или порча значения. Всё это делается во вкладке Application в DevTools.
Пример ответа
Главное отличие в том, что cookie браузер сам отправляет на сервер с каждым запросом к домену, а localStorage и sessionStorage доступны только скриптам страницы и на сервер сами не уходят. По сроку жизни: у cookie есть Expires или Max-Age, без них она живёт до конца сессии браузера; localStorage хранится, пока его не очистят; sessionStorage — пока открыта вкладка, и у каждой вкладки он свой. Cookie маленькие, около четырёх килобайт, у хранилищ — мегабайты. HttpOnly запрещает читать cookie из JavaScript, это защита от кражи сессии через XSS. Secure разрешает отправку только по HTTPS. Для тестов это значит, что я проверяю, что происходит после перезагрузки, закрытия браузера, во второй вкладке и после выхода из аккаунта — и смотрю всё это во вкладке Application.
Частые ошибки
- Сказать, что это «одно и то же хранилище, только разные названия».
- Думать, что localStorage отправляется на сервер, или что cookie недоступны скриптам всегда, а не только с HttpOnly.
- Путать sessionStorage с серверной сессией. Это разные вещи: серверная сессия обычно живёт на сервере, а в браузере остаётся только идентификатор в cookie.
- Считать, что HttpOnly шифрует cookie. Он лишь закрывает доступ из JavaScript, значение по-прежнему видно в DevTools и в запросах.
- Не связать ответ с тестированием: не назвать ни одной проверки, которую подсказывает тип хранилища.
Пример на MarketCove
В учебном магазине https://shop.tomiddle.com корзина хранится в localStorage, а после входа токен тоже кладётся в localStorage. Представьте, что вам поручили проверить эти два механизма. Набор гипотез получается почти сам собой.
Для корзины:
- добавьте товар, перезагрузите страницу и закройте браузер — корзина должна сохраниться;
- откройте магазин в окне инкогнито — корзина там пустая, и это ожидаемо: у приватного окна своё хранилище;
- найдите в Application ключ, под которым лежит корзина, и посмотрите формат значения — эта деталь пригодится в баг-репорте;
- сравните со sessionStorage: если бы корзина лежала там, она исчезала бы при закрытии вкладки.
Для входа:
- выйдите из аккаунта и посмотрите в Application, удалился ли токен;
- удалите токен вручную и откройте профиль — ожидается предложение войти, а не ошибка;
- посмотрите в Network, как токен передаётся в запросе к
/api/users/me: ожидаемо в заголовке, а не в адресе.
Отдельно полезно понимать, что заказы живут на сервере, а не в браузере: если очистить localStorage и войти снова, история заказов в профиле должна вернуться, пропадёт только корзина. А вот перезапуск сервера сотрёт и заказы, и аккаунты — они хранятся в памяти, и такую ситуацию не стоит путать с багом хранилища.
Задание для практики
Откройте любой сайт, где вы залогинены, и найдите во вкладке Application все три хранилища. Выпишите, какие cookie у них стоят с HttpOnly и Secure, а какие без, и предположите зачем. Затем найдите, где сайт хранит признак входа, и удалите его — что произойдёт при следующем действии? Для сравнения положите тестовое значение в sessionStorage через Console и проверьте, видно ли оно после перезагрузки и в новой вкладке. Закрепить навык помогут квесты по DevTools, а про то, как браузер отправляет cookie в запросе, — статья о том, что происходит после ввода адреса.
