Summary

  • Первый рабочий проект W3C о Web Storage от 23 апреля 2009 года описал покупку двух авиабилетов в разных окнах одного сайта. Общий cookie с отметкой о «текущем» рейсе способен смешать два заказа.
  • sessionStorage хранит данные по верхнему окну и происхождению сайта. localStorage предоставляет происхождению область, доступную между окнами и после сеанса, без автоматической отправки её содержимого с каждым HTTP-запросом.

Один рейс вылетает утром, другой ночью, когда кофе в аэропорту выглядит бодрее пассажиров. Человек открывает по окну на каждый вариант. В одном проверяет багаж, в другом выбирает место. Возвращается к первому, нажимает «Купить» и видит детали второго. Общий cookie честно помнит текущий рейс. Беда в том, что у путешественника сейчас два «текущих» дела.

Именно такую сцену описывает первый проект Web Storage, опубликованный W3C 23 апреля 2009 года. Если сайт ведёт заказ через cookie, выбор в одном окне может попасть в другое. Авторы допускают вполне осязаемый результат: пассажир незаметно купит два билета на один и тот же рейс. У технической ошибки появляется сумма в выписке банка.

Cookie сопровождает подходящие запросы к сайту. Серверу удобно узнавать браузер, но одной общей записи «этот рейс сейчас выбран» мало для двух одновременных покупок. Сам браузер знает, к какому верхнему окну относится каждая страница. Web Storage превратил эту границу в место, где сценарии страницы могут держать состояние.

Первый ящик назвали sessionStorage. Рекомендация W3C 2013 года выделяет область каждому верхнему контексту просмотра и каждому происхождению. Страницы бронирования в одном окне сохраняют выбранный маршрут при переходе к данным пассажира и оплате. Другое окно ведёт свой заказ. Новое связанное окно иногда начинает с копии содержимого первого, затем обе копии меняются независимо. Можно сравнить утренний рейс с ночным, не заставляя их спорить за единственную строку «текущий маршрут».

Происхождение указывает, какому сайту принадлежит область. Чужой сайт не получает свободного доступа к её содержимому. Для значения в ходе бронирования нужны два адреса: происхождение и окно. Так программа отличает выбор места на одном рейсе от выбора багажа на другом, даже если страницы выглядят одинаково и открыты у одного человека.

Второй ящик, localStorage, живёт дольше. Он принадлежит происхождению, виден его окнам и может сохраняться после сеанса просмотра. Проект предлагал хранить в браузере написанные человеком документы или данные почтового ящика. Скромный пример — счётчик посещений страницы. Cookie едет с подходящими запросами, а локальное значение остаётся в браузере, пока сценарий его не прочтёт и приложение не решит отправить. Ради цифры на счётчике не приходится прикладывать весь архив к каждому письму серверу.

Вторая редакция рекомендации 2016 года объясняет устройство ящиков. setItem, getItem, removeItem и clear работают с ключами и значениями. Неудачная запись или удаление оставляет прежнее содержимое; при нехватке места или запрете хранения setItem может вызвать QuotaExceededError. Другие документы с доступом к той же области получают событие storage, когда содержимое меняется. Сценарии должны видеть согласованные значения, хотя спецификация не заставляет каждый вызов ждать физической записи на диск.

За простым интерфейсом скрылась инженерная ссора. Раздел «Issues» рекомендации 2013 года сообщает: некоторые разработчики браузеров считали блокировку хранилища для предотвращения гонок между окнами слишком дорогой. Общий ящик должен открываться по правилам, а соблюдение очереди тоже стоит времени. Поэтому задача из билетной кассы превратилась в спор о цене согласованного состояния.

Хронология публикаций W3C проходит от проекта 2009 года до рекомендаций 2013 и 2016 годов. История двух билетов объясняет их общий замысел лучше таблицы методов. Незавершённая покупка живёт в своём окне. Долгий черновик принадлежит происхождению сайта. Cookie участвует в запросе к серверу. Когда у памяти появляется адрес, пассажир снова может выбирать рейс, а не угадывать мысли формы оплаты.