• sessionStorageは同じ閲覧画面で続ける入力の補助に使い注文や問い合わせの正本を保存しない

sessionStorageは同じ閲覧画面で続ける入力の補助に使い注文や問い合わせの正本を保存しない

公開日: 執筆:佐藤

sessionStorageは、同じ閲覧画面で複数のpageを進む間に、入力途中の選択や表示状態を保つために使います。注文、問い合わせ、予約の内容を確定した記録として保存する場所ではありません。読者の入力を戻す助けと、事業側が受け取って対応するdataを別にし、送信や確定はserver側の処理で確認します。

W3CのWeb Storageは、sessionStorageを最上位の閲覧contextごとに持つstorage areaとして定義しています。同じoriginのpageは、その閲覧contextのsessionStorageへアクセスできます。別に開いた閲覧contextは、作成時に値を引き継ぐことがあっても、その後は別のstorage areaとして扱われます。複数のtabやwindowにまたがる注文内容を一つの正本として管理する用途には向きません。

入力途中を戻すことと送信済みを記録することは別である

長いformでは、pageを一度戻ったり、確認画面から修正したりすることがあります。このとき、選んだ資料の種類、希望する連絡時間、表示中のstepのような補助的な情報をsessionStorageへ置くと、同じ閲覧画面で入力を続けやすくなります。

しかし、sessionStorageに値があることは、formが送信された証明ではありません。JavaScriptが動かなかった、保存先の容量が足りなかった、利用者がstorageを利用できない設定にした、といった場合には保存が失敗する可能性があります。W3Cの仕様でも、setItem()が保存できない場合はQuotaExceededErrorを出すことがあります。入力補助の仕組みが使えない場合にも、formを送信できる形を先に用意します。

説明用の仮例として、資料請求を三段階で受けるformを考えます。一段目で資料の種類、二段目で連絡先、三段目で確認を表示します。資料の種類と、どの段階まで進んだかをsessionStorageへ置けば、確認画面から一段目へ戻った利用者の表示を補助できます。けれども、氏名、mail address、送信内容、受付番号を確定した問い合わせとしてsessionStorageだけに置きません。送信buttonを押した後、serverが内容を受け取り、完了画面を返して初めて受付として扱います。

注文でも同じです。画面に表示する選択中の商品や個数を一時的に保つことと、在庫を引き当てること、決済を受けること、注文を受け付けることは別の処理です。閲覧画面内で「かごに入れた」と見えても、server側の在庫や注文dataが変わったとは限りません。表示のための保存と、取引を確定するdataを同じ場所に置かないことで、誰がどの時点で責任を持つかが分かれます。

sessionStorageとlocalStorageは残る範囲を分ける

sessionStorageとlocalStorageは、どちらもkeyとvalueの組でdataを扱います。けれども、残る範囲が違います。sessionStorageは閲覧contextごとにあり、その画面で進む作業に向きます。localStorageはoriginごとに持たれ、現在のsessionを越えて残る用途を想定しています。

ここで、localStorageの方が長く残るから正本に使える、と決めません。localStorageも利用者のbrowser側にある保存領域です。利用者がdataを消す、browserの設定で利用できない、別の端末から同じ内容を開く、といった場合に、事業側が受け取る正しい記録にはなりません。問い合わせや注文の正本は、server、受付system、注文systemなど、事業側が確認できる場所へ保存します。

保存するもの 向く場所 先に確認すること
同じ画面で選んだ表示tab sessionStorage 保存できなくてもpageを読めるか
複数stepで戻るための選択 sessionStorage 送信済みの内容と混ざらないか
利用者が自分で選ぶ表示設定 localStorage 消えても利用者が操作できるか
問い合わせの受付内容 serverまたは受付system 送信、受信、確認者、保管先
注文と在庫の確定 serverまたは注文system 在庫、決済、取消し、対応者

表の中で大切なのは、技術名ではなく、失われたときに誰が困るdataかです。表示中のtabが初期状態へ戻っても、読者が選び直せるなら、browser側の一時保存として扱えます。一方で、問い合わせを送ったかどうか、支払いを受けたかどうか、在庫を確保したかどうかは、読者の選び直しだけで済みません。事業側が確認できる記録が必要です。

同じoriginという条件も確認します。https://example.jp/とhttps://shop.example.jp/は、見た目には同じ会社のsiteでもoriginが異なります。HTTPとHTTPSも同じではありません。siteをHTTPSへ移す、subdomainを分ける、買い物かごを別のhostへ置く場合は、保存した値が別のpageで読めると決めつけません。画面のURL、保存する場所、送信先を分けて確認します。

keyは表示の意味が分かる名前にする

Web Storageは文字列のkeyとvalueを扱います。keyに何を入れたかが分からなければ、後から別のscriptが同じ名前を使い、表示が混ざります。dataやformのような広すぎる名前ではなく、pageと役割が分かる名前を選びます。

たとえば資料請求formの一段目で選んだ資料だけを補助するなら、request-material-choiceのように用途を表します。値に複数の項目を入れる場合は、何が入るか、いつ消すかを決めます。完了画面を表示した後まで、入力途中の値を無期限に残し続ける理由はありません。新しい問い合わせを始めたときに前の選択が残ると、利用者も担当者も内容を取り違えます。

sessionStorage.setItem('request-material-choice', selectedMaterial);

const selectedMaterial = sessionStorage.getItem('request-material-choice');

この例は、選んだ資料の名前を同じ閲覧画面で読み戻す説明です。値がない場合を必ず考えます。getItem()の結果がないときは、初期表示に戻すか、選択を求めます。保存がある前提で次のpageを進めると、直接URLを開いた人やstorageが使えない人が先へ進めません。

form送信が完了した後に消すなら、serverから成功を確認した画面でremoveItem()を呼ぶ方法が候補になります。buttonを押した瞬間に消すと、通信失敗で再入力が必要になったときに補助の値まで失われます。反対に、送信失敗の画面では値を残し、利用者が直したい項目だけを修正できるようにします。消す時点は、画面上の操作ではなく、どの状態を成功と扱うかで決めます。

個人情報を保存する前に必要性を問い直す

氏名、mail address、電話番号、住所、注文内容のような情報をbrowser側へ保存すると、同じ端末を使う別の人に見られる可能性があります。共有PC、店舗の端末、家族で使う端末では、保存した理由と利用者の期待が食い違いやすくなります。入力の手間を減らすために、必要以上の情報をsessionStorageやlocalStorageへ入れません。

W3CのWeb Storageは、persistent storageが利用者の追跡に使われるおそれや、利用者がcookieを消してもstorageが残る場合をprivacy上の論点として挙げています。これを理由に全ての保存をやめるのではなく、何を保存し、なぜ必要で、いつ消すかを決めます。読み戻しが必要な選択だけを保存し、個人情報はformの入力欄とserver側の受信処理で扱う方が、仕組みを小さくできます。

外部へform制作を頼む場合は、「途中入力を残す」とだけ依頼しません。残す項目、保存先、消す時点、storageが使えない場合の画面、送信済みの正本をどこへ残すかを渡します。JavaScriptの実装を任せても、問い合わせを受ける責任と個人情報を扱う判断はsite側に残ります。

確認では、同じ画面で次のpageへ進み、戻ったときに補助の値が出るかを見ます。次に、別のtabで同じformを開き、意図せず選択が混ざらないかを見ます。最後に、storageを消した状態やJavaScriptが動かない状態でも、formの説明を読み、入力し、送信まで進めるかを確認します。保存できた画面だけを見て、問い合わせの仕組み全体が使えると判断しません。

最初の一手は、入力途中に残したいものを一つ選び、それが失われても読者が選び直せるかを確かめることです。選び直せる表示だけをsessionStorageへ置き、問い合わせや注文の確定はserver側の完了処理で受けます。

戻る