HTTP プロトコル:フロントエンドとバックエンドの「通信言語」
🎯 核心問題
HTTP はどのように動作するのか? これは「二人はどうやって会話するのか?」と尋ねるようなものです。言語、文法、会話ルールを決める必要があります。HTTP はフロントエンドとバックエンドの間の「会話プロトコル」です。
0. HTTP の本質
HTTP(HyperText Transfer Protocol、ハイパーテキスト転送プロトコル)は、フロントエンドとバックエンドの通信の基盤プロトコルです。
0.1 会話に例える
| 会話要素 | HTTP 対応 | 説明 |
|---|---|---|
| 言語 | HTTP プロトコル | 双方が理解できる言語 |
| 文法 | リクエスト/レスポンス形式 | どのように「話す」か |
| 流れ | リクエスト-レスポンスモデル | 一問一答 |
| 終了 | 切断 | TCP 接続のクローズ |
1. HTTP の発展の歴史
HTTP は 1991 年の誕生以来、何度も大きなアップグレードを経てきました。
HTTP Protocol Demo
HTTP request
GET/api/users/123HTTP/1.1
Host:api.example.com
User-Agent:Mozilla/5.0
Accept:application/json
Authorization:Bearer xxx
TCP connection
HTTP response
HTTP/1.1200OK
Content-Type:application/json
Content-Length:156
Cache-Control:max-age=3600
{
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}
1.1 バージョン比較
| バージョン | 年 | 核心的な改善 | 典型的な特徴 |
|---|---|---|---|
| HTTP/0.9 | 1991 | GET のみサポート | プレーンテキスト、リクエストのみ、レスポンスヘッダーなし |
| HTTP/1.0 | 1996 | POST/HEAD 追加 | リクエストごとに TCP 接続 |
| HTTP/1.1 | 1997 | 持続的接続 | Keep-Alive、1 接続で複数リクエスト |
| HTTP/2 | 2015 | 多重化 | バイナリフレーム、ヘッダー圧縮 |
| HTTP/3 | 2022 | QUIC ベース | UDP 転送、ヘッドオブラインブロッキングの解決 |
💡 なぜ HTTP/2 が必要なのか?
HTTP/1.1 は持続的接続をサポートしていますが、リクエストは直列に送信する必要があります(前のリクエストのレスポンスが返ってから次のリクエストを送信)。HTTP/2 は多重化によってこの問題を解決し、複数のリクエストを同時に送信できます。
2. HTTP リクエストの構造
2.1 リクエストライン
http
GET /api/users/123 HTTP/1.13 つの部分を含みます:
- メソッド:GET、POST、PUT、DELETE など
- URL:リクエストするリソースパス
- バージョン:HTTP/1.1 または HTTP/2
2.2 リクエストヘッダー
http
Host: api.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Authorization: Bearer xxx
Content-Type: application/json
Content-Length: 45よく使われるリクエストヘッダー:
| ヘッダー | 説明 | 例 |
|---|---|---|
| Host | サーバードメイン | api.example.com |
| User-Agent | クライアント情報 | Mozilla/5.0 |
| Accept | 受け入れるレスポンスタイプ | application/json |
| Authorization | 認証情報 | Bearer token |
| Content-Type | リクエストボディのタイプ | application/json |
2.3 リクエストボディ
json
{
"name": "田中",
"email": "tanaka@example.com"
}POST、PUT、PATCH メソッドのみリクエストボディがあります。
3. HTTP レスポンスの構造
3.1 ステータスライン
http
HTTP/1.1 200 OK3 つの部分を含みます:
- バージョン:HTTP/1.1
- ステータスコード:200、404、500 など
- ステータステキスト:OK、Not Found など
3.2 レスポンスヘッダー
http
Content-Type: application/json
Content-Length: 156
Cache-Control: max-age=3600
Set-Cookie: session=xxx; HttpOnlyよく使われるレスポンスヘッダー:
| ヘッダー | 説明 | 例 |
|---|---|---|
| Content-Type | レスポンスボディのタイプ | application/json |
| Content-Length | レスポンスボディのサイズ | 156 |
| Cache-Control | キャッシュ戦略 | max-age=3600 |
| Set-Cookie | Cookie の設定 | session=xxx |
3.3 レスポンスボディ
json
{
"code": 0,
"data": {
"id": 123,
"name": "田中"
}
}4. HTTP メソッド詳細
| メソッド | 用途 | リクエストボディ | 冪等性 | 安全性 |
|---|---|---|---|---|
| GET | リソースの取得 | なし | あり | あり |
| POST | リソースの作成 | あり | なし | なし |
| PUT | 全量更新 | あり | あり | なし |
| PATCH | 部分更新 | あり | なし | なし |
| DELETE | リソースの削除 | なし | あり | なし |
| HEAD | ヘッダーの取得 | なし | あり | あり |
| OPTIONS | サポートメソッドの問い合わせ | なし | あり | あり |
4.1 GET vs POST
| 特性 | GET | POST |
|---|---|---|
| パラメータの位置 | URL クエリパラメータ | リクエストボディ |
| キャッシュ | キャッシュ可能 | デフォルトでキャッシュ不可 |
| ブックマーク | ブックマークに追加可能 | 不可 |
| 履歴 | ブラウザ履歴に保存 | 保存されない |
| データ長 | 制限あり(URL 長) | 制限なし |
| セキュリティ | パラメータが URL に見える | パラメータはリクエストボディ内 |
💡 GET/POST を使うタイミング
- GET:検索、データ取得
- POST:作成、データ送信
- PUT:全量更新(リソース全体を置換)
- PATCH:部分更新(指定フィールドのみ変更)
- DELETE:リソースの削除
5. HTTP ステータスコード
5.1 ステータスコードの分類
| 分類 | 説明 | 典型的なステータスコード |
|---|---|---|
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | リダイレクト | 301 恒久的、302 一時的、304 未変更 |
| 4xx | クライアントエラー | 400 パラメータエラー、401 未認証、404 存在しない |
| 5xx | サーバーエラー | 500 内部エラー、503 利用不可 |
5.2 よく使われるステータスコード
| ステータスコード | 説明 | 使用シーン |
|---|---|---|
| 200 OK | リクエスト成功 | GET、PUT リクエスト成功 |
| 201 Created | 作成成功 | POST リソース作成成功 |
| 204 No Content | 内容なし | DELETE 削除成功 |
| 301 Moved Permanently | 恒久的リダイレクト | URL が恒久的に変更 |
| 302 Found | 一時的リダイレクト | URL が一時的に変更 |
| 304 Not Modified | 未変更 | キャッシュ有効 |
| 400 Bad Request | パラメータエラー | リクエストパラメータ形式エラー |
| 401 Unauthorized | 未認証 | ログインが必要 |
| 403 Forbidden | 権限なし | ログイン済みだが権限不足 |
| 404 Not Found | 存在しない | リソースが存在しない |
| 500 Internal Server Error | 内部エラー | サーバー異常 |
| 503 Service Unavailable | 利用不可 | サーバーメンテナンス中または過負荷 |
6. HTTPS:安全な HTTP
6.1 HTTP vs HTTPS
| 特性 | HTTP | HTTPS |
|---|---|---|
| プロトコル | TCP | TCP + SSL/TLS |
| ポート | 80 | 443 |
| データ | 平文転送 | 暗号化転送 |
| 証明書 | 不要 | SSL 証明書が必要 |
| パフォーマンス | やや速い | やや遅い(ハンドシェイクのオーバーヘッド) |
| SEO | 影響なし | 検索エンジンが優先的に収集 |
6.2 HTTPS のワークフロー
- Client Hello:クライアントがサポートする暗号スイートを送信
- Server Hello:サーバーが証明書と選択した暗号スイートを返す
- 証明書検証:クライアントがサーバー証明書の有効性を検証
- 鍵交換:非対称暗号でセッション鍵を交換
- 暗号化通信:セッション鍵を使用して対称暗号通信
💡 HTTPS の利点
- 盗聴防止:データが暗号化され、第三者が読み取れない
- 改ざん防止:データの完全性チェック
- なりすまし防止:SSL 証明書でサーバー身元を検証
7. HTTP キャッシュ機構
7.1 キャッシュヘッダー
| ヘッダー | 説明 | 例 |
|---|---|---|
| Cache-Control | キャッシュ戦略 | max-age=3600 |
| ETag | リソースバージョン番号 | "33a64df551425fcc" |
| Last-Modified | 最終更新日時 | Wed, 21 Oct 2015 07:28:00 GMT |
7.2 キャッシュ戦略
強キャッシュ:
http
Cache-Control: max-age=36003600 秒以内、ブラウザは直接キャッシュを使用し、リクエストを送信しません。
条件付きキャッシュ:
http
ETag: "33a64df551425fcc"ブラウザが If-None-Match を送信し、サーバーが 304(未変更)または 200(変更済み)を返します。
8. よくある質問
8.1 GET と POST の本質的な違い
誤解:GET と POST の違いはパラメータの位置だけ。
真実:
- GET は冪等で、複数回リクエストしても結果は同じ
- POST は非冪等で、複数回リクエストすると複数のリソースが作成される可能性がある
- GET はキャッシュ可能、POST はデフォルトでキャッシュ不可
- GET はブックマークに保存可能、POST は不可
8.2 HTTP/1.1 のヘッドオブラインブロッキング
問題:HTTP/1.1 は持続的接続をサポートしていますが、リクエストは直列に送信する必要があります。前のリクエストの応答が遅いと、後続のリクエストもすべて待たされます。
解決策:
- HTTP/2 の多重化
- ドメインシャーディング(複数ドメインで複数接続を確立)
- 接続プール(同時接続数を制限)
8.3 HTTP/2 の利点
| 特性 | HTTP/1.1 | HTTP/2 |
|---|---|---|
| 転送形式 | テキスト | バイナリフレーム |
| 多重化 | 非対応 | 対応 |
| ヘッダー圧縮 | なし | HPACK アルゴリズム |
| サーバープッシュ | 非対応 | 対応 |
用語早見表
| 用語 | 英語 | 説明 |
|---|---|---|
| HTTP | HyperText Transfer Protocol | ハイパーテキスト転送プロトコル |
| HTTPS | HTTP Secure | HTTP + SSL/TLS |
| TCP | Transmission Control Protocol | 伝送制御プロトコル |
| SSL/TLS | Secure Sockets Layer | セキュアソケットレイヤー |
| 冪等性 | Idempotent | 複数回リクエストしても結果が同じ |
| 持続的接続 | Keep-Alive | 1 つの TCP 接続で複数リクエストを送信 |
| 多重化 | Multiplexing | 複数リクエストを同時に送信 |
| ヘッドオブラインブロッキング | Head-of-Line Blocking | 前のリクエストが後続のリクエストをブロックすること |