フォームと入力の検証 — 画面の検証は親切、サーバーの検証は守り
申し込みフォームで、送信ボタンを 2 回押した人に申し込みが 2 件でき、エラーで戻った人の入力は全部消えていた。画面の検証を足しても、サーバーを通る値は守れない。役割の違う 2 つの検証を、別のものとして設計する。
この記事の進み方
What — 2 つの検証は、役割が違う
フォームの検証には、画面(ブラウザ)での検証と、サーバーでの検証があります。似たことを確かめますが、目的が違います。
| 画面の検証 | サーバーの検証 | |
|---|---|---|
| 目的 | 利用者を助ける。間違いを早く知らせる | データを守る。不正な値を入れない |
| すり抜けられるか | すり抜けられる(開発者ツール・直接の送信) | すり抜けられない(最後の関門) |
| 無くてもよいか | 無くても動く(不親切になるだけ) | 無いと、何でも入る |
| 確かめられること | 形(空欄・書式・範囲) | 形に加えて、DB と照らすこと(満席・重複・権限) |
画面の検証は、利用者の手元で動くので、利用者が止められます。開発者ツールで送信の中身を書き換える、API を直接呼ぶ。どちらも画面の検証を通りません。だから、データを守るのはサーバーの検証だけです。
そして、満席かどうか、同じメールで申し込み済みかどうかは、DB を見ないと分かりません。画面では確かめようがない検証もあります。
押したら送る。失敗したら画面を作り直す。
押す → 送る (反応が遅い) もう一度押す → もう一度送る → 申し込み 2 件 満席で失敗 → 画面を作り直す → 入力が全部消える
- 二重送信
- 起きる
- 失敗したときの入力
- 消える
- 作る手間
- 無い
- 不正な値
- —
- –冒頭の事故の 1 と 2。
- –利用者は、押したのに反応が無ければ、もう一度押す。それは正しい行動。
同じフォームでも、送信中と失敗したときの扱いで、利用者の体験とデータが変わる。
画面で参加人数を 1〜10 に制限しているのに、DB に「-3」が入っていました。直すべき場所はどこですか?
エラーの見せ方
サーバーがエラーを返したとき、利用者が次に何をすればよいかが分かる形で見せます。
- 入力を消さない。長い備考を書き直させない
- どの欄の問題かを、その欄のすぐ近くに出す。ページの上に「エラーがあります」とだけ出しても、長いフォームでは見つからない
- 最初のエラーの欄に、カーソルを移す。画面を読み上げる道具を使う人にも、エラーがあったことが伝わる
- 満席のように欄に紐づかないエラーは、フォームの上にはっきり出し、次の行動(キャンセル待ち・別の日程)を示す
エラー設計の記事で見たとおり、サーバーはどの欄の、どんな問題かを機械が読める形で返します。画面はそれを欄に振り分けて表示します。
Why — なぜ同じ検証を 2 回書くのか
同じ規則を 2 か所に書くのは、重複ではないのか
「参加人数は 1〜10」という規則を、画面とサーバーの両方に書くことになります。凝集度と結合度で見た「同じ知識を 2 か所に書かない」に反するように見えます。
実際、規則が 2 か所にあると、片方だけ変えるずれが起きます。上限を 20 に上げたのに画面だけ 10 のまま、など。これを避けるには、規則を 1 か所に書き、画面とサーバーの両方から使う形が理想です。同じ言語で書いているなら、検証の規則を共有できます。
共有できない場合は、サーバーを正にします。画面の検証がずれていても、困るのは親切さだけです。サーバーがずれると、データが壊れます。
反応が遅いと、人はもう一度押す
二重送信は、利用者の不注意ではありません。押したのに反応が無ければ、もう一度押すのが正しい行動です。原因は、押したことが伝わっていない画面の側にあります。
押した瞬間に「送信中」と表示してボタンを押せなくすると、押したことが伝わり、もう一度押す理由がなくなります。これは二重送信を減らすと同時に、体験そのものを良くします。
二重送信を「どこから送られても」1 件にするために、必要なものはどれですか?
演習 — まず自分で判断する
解説を読む前に、まず自分で判断してみてください。ここで一度詰まっておくと、 次の節の判断軸が「なるほど」ではなく「そう来たか」に変わります。
冒頭の申し込みフォームを、どう直しますか?
- 二重送信の申し込みが月 40 件。送信ボタンを押してから応答まで 2〜3 秒かかる
- 満席などでサーバーがエラーを返すと、入力がすべて消える
- 参加人数に、負の数や 500 が入っている。画面では 1〜10 に制限している
- フロントエンドとサーバーは、同じ TypeScript で書いている
- · データを守る検証はどこにあるか
- · 二重送信を、画面とサーバーのどちらで、何のために防ぐか
- · エラーのあと、利用者の入力と次の行動はどうなるか
「画面でしっかり検証しているから、サーバーの検証は最低限でいい」と言うフロントエンド担当に、サーバーの検証が要る理由を説明してください
- 相手は画面の検証を丁寧に作っていて、利用者の体験を大事にしている
- 相手は、開発者ツールで送信の中身を書き換えられることを意識していない
- 画面の検証の価値も認めたうえで話したい
読み終わりましたか?
読了にすると、これを前提とする記事がロードマップで開放されます。