HTTPリクエストにおけるリンクとフォームの違い
ユーザーがナビゲーションリンクをクリックしたり、検索クエリを送信したりするたびに、ブラウザはHTTPリクエストを送信します。しかし、どのHTML要素がそのリクエストをトリガーし、どのように動作するかは、多くの開発者が認識している以上に重要です。<a>と<form>のどちらを選択するかは、単なるマークアップの好みの問題ではありません。これは、動作、セキュリティ、正確性に影響を与えるセマンティックな決定なのです。
重要なポイント
- リンク(
<a>)はナビゲーション用で、通常GETリクエストをトリガーします。フォーム(<form>)はデータ送信用で、GETとPOSTの両方をサポートします。 - ユーザー入力がURLを形成する場合(検索クエリなど)はGETフォームを使用し、アクションがサーバーの状態を変更する場合(アカウント作成など)はPOSTフォームを使用します。
method="link"は無効なHTMLです。ブラウザは黙ってGETにフォールバックするため、予期しない動作につながる可能性があります。- HTMLフォームはネイティブでGETとPOSTのみをサポートします。PUT、PATCH、DELETEを使用する場合は、JavaScriptを使用してください。
基本的な違い:HTMLのナビゲーションと送信
リンク(<a>)はナビゲーション要素です。 ブラウザに「このリソースを取得してください」と指示します。リンクをクリックすると、通常、href属性のURLへのGETナビゲーションリクエストがトリガーされます。それだけです。ユーザー入力は収集されず、データはシリアライズされません。単純なナビゲーションイベントです。
フォーム(<form>)はデータ送信要素です。 ユーザーから入力を収集し、サーバーに送信します。フォームは、リクエストの性質に応じて、GETまたはPOSTのいずれかを使用できます。
以下は簡単な比較表です:
| 特徴 | <a>リンク | <form> |
|---|---|---|
| 目的 | ナビゲーション | データ送信 |
| HTTPメソッド | GETのみ | GETまたはPOST |
| ユーザー入力の収集 | なし | あり |
| 右クリック/新しいタブで開く | 可能 | 不可 |
| SEOクローラビリティ | あり | 限定的 |
| サーバー状態の変更 | なし | あり(POSTの場合) |
HTMLフォームにおけるGETとPOST:それぞれの使い分け
安全で冪等なナビゲーションにはリンクを使用
アクションがサーバー上で何も変更せず、宛先がブックマークまたは共有可能な場合は、リンクを使用します:
<a href="/articles/html-basics">Read the HTML guide</a>
リンクは安全で、冪等で、キャッシュ可能です。まさにGETリクエストがあるべき姿です。
ユーザー入力がURLを形成する場合はGETフォームを使用
検索ボックスが典型的な例です。ユーザーがクエリを入力すると、フォームはそれをクエリ文字列としてURLに追加します:
<form method="get" action="/search">
<input type="search" name="q" placeholder="Search...">
<button type="submit">Search</button>
</form>
これにより/search?q=your+queryが生成されます。共有可能でブックマーク可能なURLです。リクエストが依然として安全で冪等であるが、URLパラメータがユーザー入力に依存する場合は、GETフォームを使用します。
アクションに副作用がある場合はPOSTフォームを使用
アカウントの作成、支払いの送信、コメントの投稿など、すべてサーバーの状態を変更します。これらはPOSTフォームに属します:
<form method="post" action="/register">
<input type="email" name="email">
<input type="password" name="password">
<button type="submit">Create account</button>
</form>
POSTはデータをURLではなくリクエストボディで送信します。これは機密データや非冪等アクションに適しています。
Discover how at OpenReplay.com.
よくある間違い:method="link"は存在しません
一部の開発者は「リンクボタン」を作成しようとして<form method="link">と書きます。これは無効なHTMLです。ブラウザは未知の値を無視し、デフォルト(GET)にフォールバックします。フォームは依然として送信されますが、黙って誤って送信されます。
どこかにナビゲートするボタンが必要な場合は、フォームではなく、ボタンとしてスタイル設定されたリンクを使用してください:
<!-- ❌ 無効 -->
<form method="link" action="/about">
<input type="submit" value="Go to About">
</form>
<!-- ✅ 正しい -->
<a href="/about" class="btn">Go to About</a>
知っておくべき最新のフォーム機能
HTML5では、formactionおよびformmethod属性を介したボタンごとのオーバーライドが追加され、個々の送信ボタンがフォームの送信先や送信方法を変更できるようになりました:
<form method="post" action="/save">
<button type="submit">Save</button>
<button type="submit" formaction="/save-and-publish" formmethod="post">Publish</button>
</form>
また注目すべき点として、requestSubmit()は(submit()とは異なり)送信前にフォーム検証をトリガーするため、JavaScriptでプログラム的にフォームを送信する場合により良い選択肢となります。
PUT、PATCH、DELETEについては、HTMLフォームはこれらをネイティブでサポートしていません。JavaScript(fetch、XMLHttpRequest)またはサーバー側のメソッドオーバーライド規約を使用する必要があります。
まとめ
リンクとフォームの選択は、セマンティクスを理解すれば簡単です:
- ページへのナビゲーション? リンクを使用します。
- クエリのためのユーザー入力の収集? GETフォームを使用します。
- サーバーの状態を変更するデータの送信? POSTフォームを使用します。
- PUT/PATCH/DELETEの実行? JavaScriptを使用します。
アクションの意図に合った要素を選択してください。セマンティックHTMLは正確性だけの問題ではありません。それはUIを予測可能で、アクセシブルで、保守可能にするものなのです。
よくある質問
技術的には可能ですが、通常は誤ったセマンティックな選択です。GETフォームは、ユーザー入力を収集し、それをクエリパラメータとしてURLに追加するように設計されています。ユーザー入力のない単純なナビゲーションには、リンクが正しいセマンティックな選択です。リンクは検索エンジンによってクロール可能で、右クリックのコンテキストメニューをサポートし、ブラウザと支援技術の両方にナビゲーションの意図を明確に伝えます。
ブラウザは認識できないメソッド値を無効として扱い、黙ってデフォルトのフォームメソッドであるGETにフォールバックします。したがって、method linkを指定したフォームは依然として送信されますが、GETフォームとまったく同じように動作します。これはバグを隠蔽し、混乱を招く動作を生み出す可能性があります。フォームのメソッド値には常にgetまたはpostを使用してください。
submit()メソッドは、組み込みのHTML検証を実行したり、submitイベントを発火させたりせずに、フォームを即座に送信します。requestSubmit()メソッドは、ユーザーが送信ボタンをクリックしたかのように動作します。最初に制約検証をトリガーし、submitイベントを発火させるため、イベントリスナーが送信をインターセプトまたはキャンセルできます。検証を実行する必要がある場合は、requestSubmit()を使用してください。
HTMLフォームはメソッド値としてGETとPOSTのみをサポートします。DELETE、PUT、またはPATCHリクエストを送信するには、fetchまたはXMLHttpRequestを使用したJavaScriptが必要です。一部のサーバー側フレームワークは、意図したHTTPメソッドを指定する隠し入力フィールドを含むPOSTフォームを送信し、サーバーがそれに応じて解釈するメソッドオーバーライドパターンもサポートしています。
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.