Summary

  • 2009年4月23日のW3C Web Storage作業草案は、同じサイトで航空券を二つのウィンドウから予約する例を挙げた。予約中の便を共有クッキーで管理すると、片方の選択がもう片方へ紛れ込む。
  • sessionStorageはトップレベルのウィンドウとオリジンに結び付き、localStorageはオリジンで共有され、利用期間も長い。画面の作業とサイトの記憶を別の住所に置く仕組みだった。

旅行者はまだ迷っている。朝の便なら到着後に一日使える。深夜の便なら料金は安いが、空港の椅子と長い付き合いになる。二つのウィンドウを並べて座席と荷物を調べ、片方へ戻って購入ボタンを押す。そこで違う便の情報が現れたら、旅行の計画はコメディになり、支払いだけが真顔で進む。

W3Cが2009年4月23日に公開したWeb Storageの最初の作業草案は、まさに二つの航空券予約を例にした。サイトがクッキーに「現在の便」を記録すると、同じサイトの別ウィンドウがその値を上書きしてしまう。草案は、客が気付かないまま同じ便の切符を二枚買う可能性まで描く。規格文書の例としては珍しく、間違いの値段がすぐ分かる。

クッキーは対象サイトへのHTTPリクエストに付いていく。サーバーがブラウザーを識別するには便利だ。ただ、旅行者が同じサイトで二つの手続きを同時に進めると、「現在」という言葉が二通りになる。ブラウザー自身は各文書がどのトップレベルのウィンドウに属するか知っている。Web Storageは、その境界をスクリプトが使える記憶の住所にした。

一つ目の引き出しがsessionStorageだ。2013年のW3C勧告では、トップレベルの閲覧コンテキストごと、オリジンごとに保存領域を持つ。同じウィンドウで予約画面から旅客情報へ進んでも、その便について入力した値を読める。もう一つのウィンドウには別の領域がある。元のウィンドウから新しく開いた画面は最初に内容を複製することがあるが、その後の変更はそれぞれ独立する。旅程を二本並べるとき、片方のメモが勝手にもう片方の予定表にならない。

オリジンも住所の一部だ。別のサイトはこの領域を自由に開けない。予約中の値を探すには、どのサイトの、どのウィンドウの情報かが必要になる。利用者には当然に見える区別でも、プログラムが保存先を間違えると、画面だけが別々で中身は一つの引き出しを奪い合う。

二つ目はlocalStorage。こちらはオリジンの領域で、同じサイトの複数のウィンドウから使え、一回の閲覧が終わっても残せる。草案は、利用者が書いた文書やメールのデータをブラウザーに置く用途を挙げた。小さな例としては訪問回数のカウンターがある。クッキーなら条件に合うリクエストのたびにネットワークへ同伴するが、ローカルの値はブラウザー内に置かれ、スクリプトが読み、アプリが送信を決める。数を覚えるためだけに、毎回の通信へ帳簿を添える必要がなくなった。

2016年の第二版勧告は、引き出しの操作も定めている。setItem、getItem、removeItem、clearでキーと値を扱う。容量不足や保存を許さない設定で書き込みが失敗すれば、古い状態が残り、QuotaExceededErrorが生じ得る。共有する保存領域が変わると、ほかの文書にstorageイベントが届く。スクリプトから見える整合性は求められる一方、毎回の呼び出しで物理ディスクへの書き込み完了を待つ決まりはない。

簡単そうな道具にも渋滞がある。2013年勧告の課題欄には、複数のウィンドウでの競合を防ぐ保存領域のロックが重すぎる、という実装者の声が記された。二つの画面で同じ引き出しを使うなら、読み書きの順番をどう守るかが問題になる。航空券の小話の裏側には、ブラウザー全体の性能をめぐる実務的な論争があった。

W3Cの公開履歴には、2009年の草案から2013年、2016年の勧告までの足跡が残る。切符の例が示す問いは変わらない。進行中の予約はどのウィンドウに属するのか。サイトに残す下書きはどのオリジンに属するのか。サーバーへの通信には何を載せるのか。住所を決めてから値をしまえば、予約画面はようやく旅行者の予定に追いつける。