お問い合わせや検索、ログインなど、ユーザーが入力した内容をサーバーへ送る入れ物になるのが form 要素です。入力欄やボタンをいくつ並べても、それらを form で囲んで送信先と送信方法を決めなければ、データはどこにも送られません。この記事では form 要素の基本から、action・method・enctype といった主要な属性の意味、GET と POST の違い、送信ボタンの作り方までを、初心者にも分かるように解説します。
目次
form 要素とは
form は、ユーザーが入力した値をまとめてサーバーへ送るための要素です。テキスト入力欄(input)やプルダウン(select)、複数行入力欄(textarea)などの「フォーム部品」を form の中に置き、送信ボタンが押されたときに、その中身を一括で送信します。
逆に言うと、入力欄だけを置いても form で囲んでいなければ、ブラウザはそれを「送信できるまとまり」として扱いません。データの送り先(action)と送り方(method)を決める役割を持つのが、この form 要素です。
基本の使い方
もっとも基本的な形は、form で入力欄と送信ボタンを囲み、action に送信先の URL、method に送信方法を指定するだけです。次は名前を入力して送信するシンプルな例です。
<form action="/contact" method="post">
<label for="name">お名前</label>
<input type="text" id="name" name="username">
<button type="submit">送信する</button>
</form>
送信ボタンが押されると、ブラウザは action で指定した /contact へ、method で指定した方法(ここでは POST)で入力内容を送ります。このとき送られるのは、各入力欄の name 属性とその値のペアです。name が付いていない入力欄の値は送信されないため、送りたい項目には必ず name を付けます。
上の例で id="name" と name="username" が別々なのに注意してください。id は label と結び付けるためのもの、name は送信されるデータの「キー(項目名)」です。役割が違うので、混同しないようにしましょう。
form の主な属性
form には送信の挙動を決める属性がいくつかあります。代表的なものを下の表にまとめました。
| 属性 | 説明 |
|---|---|
action | 入力内容の送信先 URL を指定する |
method | 送信方法を指定する(get または post) |
enctype | 送信データの形式(エンコード方式)を指定する |
name | フォーム自体の名前。スクリプトから参照するときに使う |
target | 送信結果をどこに表示するか(_blank で別タブなど) |
autocomplete | 入力の自動補完を有効・無効にする(on / off) |
novalidate | 送信時のブラウザによる入力チェックを無効にする |
このうち日常的によく触るのが action・method・enctype の3つです。順番に見ていきます。
action で送信先を指定する
action は、入力内容を受け取って処理するプログラム(URL)を指定します。サイト内のパスでも、別ドメインの完全な URL でも構いません。
<!-- サイト内の処理先に送る -->
<form action="/api/contact" method="post"> ... </form>
<!-- 別ドメインのサービスに送る -->
<form action="https://example.com/submit" method="post"> ... </form>
action を省略すると、いまフォームが置かれているページ自身に送信されます。同じページで入力を受け取って処理する場合は省略しても動きますが、送り先を明確にするため、基本的には書いておくのがおすすめです。
method で送信方法を指定する(GET と POST)
method には get と post の2つがあります。どちらも入力内容をサーバーへ送りますが、送り方が大きく異なります。
GET は URL に付けて送る
method="get" の場合、入力内容は ? 以降のクエリ文字列として URL の末尾に付けられて送られます。たとえば検索キーワードに「html」と入れて送信すると、次のような URL になります。
/search?keyword=html&category=blog
URL に値が残るため、その URL をブックマークしたり共有したりすれば、同じ検索結果を再現できます。検索や絞り込みのように「結果のページを共有したい」「同じ条件を後から開きたい」用途に向いています。一方で、入力内容が URL に丸見えになり、ブラウザの履歴にも残るので、パスワードや個人情報を送るのには使いません。送れるデータ量にも上限がある点にも注意します。
POST は本文に入れて送る
method="post" の場合、入力内容は URL ではなくリクエストの本文(ボディ)に入れて送られます。URL には値が現れないため、お問い合わせ・ログイン・会員登録のように、外から見えてほしくない情報やデータ量の多い送信に向いています。
判断の目安として、「サーバー上のデータを取得・検索するだけ」なら GET、「サーバーに何かを登録・更新する」「秘密にしたい値を含む」なら POST と覚えておくとよいでしょう。GET と POST の違いを表にまとめます。
| 観点 | GET | POST |
|---|---|---|
| 送る場所 | URL のクエリ文字列 | リクエストの本文 |
| URL に残るか | 残る(共有・再現できる) | 残らない |
| 向く用途 | 検索・絞り込みなど | 登録・ログインなど |
| 機密情報 | 不向き | こちらを使う |
なお POST は「見えない」だけで、それ自体が暗号化されるわけではありません。機密情報を安全に送るには、サイト全体を HTTPS で配信することが前提になります。
enctype でファイル送信に対応する
enctype は、POST で送るときのデータの形式(エンコード方式)を指定する属性です。指定できる値は次の3つです。
| 値 | 説明 |
|---|---|
application/x-www-form-urlencoded | 既定値。通常のテキスト入力はこれで送られる |
multipart/form-data | ファイルを送るときに使う形式 |
text/plain | 値をそのまま平文で送る(実用ではほぼ使わない) |
ふだんのテキスト送信では既定値のままでよく、enctype を書く必要はありません。意識する必要があるのは、ファイルをアップロードするときです。input type="file" でファイルを送る場合は、enctype="multipart/form-data" を必ず指定します。
<!-- ファイル送信には multipart/form-data が必須 -->
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="photo">写真を選択</label>
<input type="file" id="photo" name="photo">
<button type="submit">アップロード</button>
</form>
この指定を忘れると、サーバー側にはファイルの中身ではなくファイル名だけが届き、アップロードが正しく行われません。ファイルを扱うフォームでは method="post" と enctype="multipart/form-data" をセットで覚えておきましょう。
送信ボタンとリセットボタン
フォームを送信するには、送信ボタンが必要です。button type="submit" か、input type="submit" のどちらでも作れます。button は開始タグと終了タグの間に文言やアイコンを自由に入れられるため、近年はこちらがよく使われます。
<!-- どちらも「送信」ボタンになる -->
<button type="submit">送信する</button>
<input type="submit" value="送信する">
<!-- 入力内容を初期状態に戻すボタン -->
<button type="reset">入力をクリア</button>
ひとつ注意したいのが、form の中に置いた button は type を省略すると submit 扱いになることです。送信目的ではないボタン(たとえば JavaScript で何かを実行するだけのボタン)には、必ず type="button" を指定します。これを忘れると、押した瞬間にフォームが送信されてページが再読み込みされてしまいます。
送信前に入力をチェックする
HTML だけでも、入力欄に属性を付けるだけで簡単な入力チェック(バリデーション)ができます。required を付けた欄が空のまま送信されると、ブラウザが警告を出して送信を止めてくれます。type="email" ならメールアドレスの形式かどうかも確認されます。
<form action="/contact" method="post">
<label for="email">メールアドレス</label>
<!-- 必須・メール形式をブラウザがチェックする -->
<input type="email" id="email" name="email" required>
<button type="submit">送信する</button>
</form>
このチェックを一時的に無効にしたいときは、form に novalidate を付けます。ただしブラウザ側のチェックはあくまで補助です。送られてきた値が正しいかどうかは、最終的にサーバー側でも必ず検証する必要があります。利用者が開発者ツールで属性を書き換えれば、HTML のチェックは簡単にすり抜けられるためです。
送信してもデータが届かないとき
入力欄に name が付いていない
もっとも多いつまずきが、入力欄に name 属性を付け忘れているケースです。送信されるのは「name の値」と「入力値」のペアなので、name がない欄はそもそも送信対象になりません。サーバー側で値が空・未定義になるときは、まず name が付いているかを確認しましょう。id だけ付けても送信には関係しない点に注意します。
送信ボタンが form の外にある
送信ボタンや入力欄が form タグの外側に置かれていると、それらは送信のまとまりに含まれません。レイアウトの都合で div の入れ子が深くなったときに起こりがちです。HTML の構造上どうしても外に出したい場合は、ボタンや入力欄に form="フォームのid" を指定すると、離れた場所にあっても結び付けられます。
ファイルが届かない
ファイルを選んだのに中身が届かないときは、enctype="multipart/form-data" が指定されているか、method が post になっているかを確認します。GET ではファイルを送れないため、この2つはセットで必要です。
まとめ
form 要素は、入力内容をまとめてサーバーへ送るための土台です。要点を振り返ります。
actionで送信先、methodで送信方法を指定する- 検索・絞り込みなど共有したい用途は GET、登録・ログインなど秘密にしたい送信は POST
- ファイルを送るときは
method="post"とenctype="multipart/form-data"をセットで使う - 送りたい入力欄には必ず
nameを付ける(送信のキーになる) - 送信目的でない
buttonにはtype="button"を付ける requiredなどで簡易チェックはできるが、最終的な検証はサーバー側で行う
まずは action・method と name 付きの入力欄、送信ボタンという最小構成から始め、用途に応じて enctype やバリデーションを足していくのがおすすめです。