HTML5のrequired属性は入力必須を示すがサーバー側でも検査する
公開日: 執筆:佐藤
HTML5のrequired属性は、フォームを送信する前に値が必要な入力欄を示します。input、select、textareaへ指定でき、空のまま送信しようとした場合はブラウザの制約検証の対象になります。
ただし、requiredはサーバー側の入力検査を置き換えません。ブラウザで空欄を止める処理と、サーバーが受け取った値を検査する処理は、目的も実行場所も違います。両方を用意します。
required属性は値ではなく属性の有無で指定する
requiredは真偽を属性の有無で示すブール属性です。次の三つは、いずれも入力必須を示します。
<input type="text" name="company" required>
<input type="text" name="company" required="">
<input type="text" name="company" required="required">
反対に、required="false"と書いても任意入力にはなりません。属性が存在するため、入力必須として扱われます。任意入力へ戻す場合は、required属性そのものを取り除きます。
HTML5のフォーム仕様は、requiredが指定され、変更できる入力欄の値が空なら、値が欠けている状態として扱います。どの項目を事業上の必須項目にするかを決める属性ではなく、決めた結果をHTMLへ示す属性です。
input、select、textareaでは空の意味が違う
一行入力欄と複数行入力欄では、値が空なら未入力です。
<label for="email">メールアドレス 必須</label>
<input type="email" id="email" name="email" required>
<label for="message">お問い合わせ内容 必須</label>
<textarea id="message" name="message" required></textarea>
選択欄では、最初から具体的な選択肢が選ばれていると、利用者が操作しなくても値が入っています。選択を求める場合は、空の値を持つ案内用の選択肢を先頭へ置きます。
<label for="inquiry-type">お問い合わせ種別 必須</label>
<select id="inquiry-type" name="inquiry_type" required>
<option value="">選択してください</option>
<option value="estimate">見積もりについて</option>
<option value="support">利用中のサービスについて</option>
</select>
値が空の先頭項目を残したまま送信すると、選択欄は未入力として扱われます。画面に「選択してください」と書くだけで、valueへ同じ文字を入れてしまうと、空の値ではありません。
requiredを指定できない入力形式もあります。たとえば、type="hidden"は利用者が入力する欄ではなく、制約検証の対象になりません。すべてのinputへ機械的に付けず、利用者が値を入力または選択する欄へ指定します。
必須表示とHTML上の指定をそろえる
画面に「必須」と書いたのにrequiredがなく、サーバーも空欄を受け付ける状態では、表示と動作が一致しません。反対に、画面では任意に見えるのにrequiredだけが付いていると、送信時になって初めて入力を求められます。
各入力欄について、次の三つを同じ判断へそろえます。
| 対象 | 役割 |
|---|---|
| ラベルや説明 | 利用者へ必須か任意かを伝える |
required属性 |
ブラウザの制約検証へ入力必須を示す |
| サーバー側の検査 | 受信した値が必要条件を満たすか確認する |
必須の印に星印を使うなら、最初に星印の意味を説明します。入力欄の名前と操作対象は、label要素でも関連付けます。見た目、HTML、受信処理のどれか一つだけを直して終わらせないことが重要です。
required属性だけでは不正な送信を防げない
HTML5の制約検証は、入力中の誤りを送信前に知らせるための仕組みです。サーバーへ届く値が安全であることまでは保証しません。
HTML5のセキュリティに関する規定は、サーバーがクライアント側の検証へ依存してはいけないとしています。利用者が意図して検証を避ける場合だけでなく、この機能を実装しない古いブラウザや自動処理から送信される場合もあるためです。
サーバー側では、少なくとも次の点を、画面側とは別に確認します。
- 必須値が存在するか
- 文字数や形式が受け付ける条件に合うか
- 選択値が用意した候補に含まれるか
- 保存、メール送信、画面表示へ渡す前に必要な処理を行ったか
ここで扱うのは説明用の一般例です。個人情報の保存、本人確認、決済などに必要な条件は、フォームの目的と運用に応じて別に決めます。
novalidateがある送信経路も確認する
form要素へnovalidate属性がある場合は、フォーム送信時の制約検証を行いません。送信ボタンのformnovalidate属性によって、そのボタンからの送信だけ検証を行わない構成も作れます。
<form action="confirm.php" method="post" novalidate>
<input type="email" name="email" required>
<button type="submit">送信する</button>
</form>
この例では、入力欄にrequiredがあっても、フォームの送信時検証は無効です。制作途中の確認用にnovalidateを付けたなら、公開前に残っていないか確かめます。一方、意図して検証を無効にする場合も、サーバー側の検査は必要です。
一つの入力欄を空にして送信経路を確かめる
実装後は、フォーム全体を眺めるだけでなく、必須欄を一つ空にして送信します。ブラウザで送信が止まるかを確認したあと、サーバー側の検査も単独で確かめます。
確認結果には、対象項目、HTMLの指定、画面上の必須表示、サーバー側の条件、空欄時の結果を残します。制作会社へ実装を依頼しても、この条件表とテスト結果はサイト運営者が確認できる場所へ置きます。
最初の一手は、問い合わせフォームの必須項目を一つ選ぶことです。その項目について、ラベル、required属性、サーバー側の検査が同じ条件になっているかを比べてください。
関連記事

