Webサーバー・インフラ
HTTPリクエスト・HTTPレスポンス
post:
HTTPリクエストは、WebブラウザなどのクライアントがWebサーバーへ送る要求です。 HTTPレスポンスは、その要求に対してサーバーが返す応答です。 Webページの表示やAPIの利用では、このリクエストとレスポンスのやり取りが繰り返されています。
HTTPリクエスト・HTTPレスポンスとは?
HTTP(Hypertext Transfer Protocol)は、クライアントとサーバーの間でデータをやり取りするためのプロトコル、つまり通信の手順やデータの意味を定めた規則です。 Webブラウザでページを開く場合は、ブラウザが「このページを取得したい」というHTTPリクエストを送り、サーバーが処理結果やページのデータをHTTPレスポンスとして返します。
クライアントとは要求を送る側のソフトウェアを指します。
Webブラウザのほか、curlやwgetなどのコマンド、スマートフォンアプリ、Web APIを利用するプログラムもHTTPクライアントになります。
Webページを開いたときの基本的な流れ
例えば、ブラウザからhttps://example.com/aboutへアクセスするとします。
ブラウザは/aboutで示されるリソースを取得するよう要求します。
リソースとは、URLで指定するページや画像、APIのデータなど、HTTPで操作する対象のことです。
- ブラウザがWebサーバーへHTTPリクエストを送る
- WebサーバーやWebアプリケーションがリクエストを処理する
- 正常に取得できれば、サーバーがHTMLなどのデータをHTTPレスポンスとして返す
- ブラウザがHTMLを読み取り、必要に応じてCSS、JavaScript、画像などを追加でリクエストする
- 取得したデータを使ってページを表示する
HTTPで送受信するのはHTMLだけではありません。CSS、JavaScript、画像、JSON、PDF、動画や音声なども扱えます。 そのため、1ページの表示でも複数のリクエストとレスポンスが発生することがあります。 ただし、ブラウザに保存されたデータを再利用できる場合は、サーバーへの通信を省けることもあります。
HTTPリクエストの中身
HTTPリクエストには、どのリソースに対して何をしたいのか、どのような形式のデータを受け取りたいのか、といった情報を含めます。 ここではHTTP/1.1の形式を使って説明します。次は、HTMLを取得するリクエストの例です。
GET /about HTTP/1.1
Host: example.com
Accept: text/html
先頭の行をリクエスト行と呼び、HTTPメソッド、リクエスト対象、HTTPのバージョンを並べます。 続く行がHTTPヘッダーで、空行がヘッダー部の終わりを示します。 送信するデータ本体であるメッセージボディがある場合は、この空行の後に続きます。上の例にはボディがありません。
実際のHTTP/1.1では、開始行やヘッダー行の区切りにCRLFという改行を使います。
記事内では通常の改行として表示しています。
HTTPメソッド
HTTPメソッドは、対象のリソースに対して行いたい操作を示します。 代表的なものには次があります。
| メソッド | 主な用途 |
|---|---|
GET | リソースの内容を取得する |
POST | データを送り、対象のリソースに応じた処理を依頼する |
PUT | 送信した内容で、指定したリソースを作成・置換する |
PATCH | リソースに部分的な変更を適用する |
DELETE | 指定したリソースの削除を要求する |
Webページの表示ではGETがよく使われます。
フォームの入力値やAPIで処理するデータを送る場合は、POSTなどが使われます。
リクエスト対象
上の例では/aboutがリクエスト対象です。
HTTP/1.1でサーバーへ直接送る通常のリクエストでは、URLのパスと、存在する場合はクエリ文字列を指定します。
例えばhttps://example.com/search?q=httpなら、対象は/search?q=httpとなります。
Webサーバーはこの情報をもとに公開ファイルを探したり、Webアプリケーションの対応する処理へ振り分けたりします。 URLのパスが、サーバー内のファイルの場所と常に一致するわけではありません。 公開ファイルとURLの対応については、ドキュメントルートの解説で扱っています。
HTTPヘッダー
HTTPヘッダーは、メッセージを処理するための情報を名前と値の組で伝えます。
例にあるHost: example.comは接続先のホストを、Accept: text/htmlはクライアントが受け取れるデータ形式を示します。
ほかに、クライアントのソフトウェア情報を伝えるUser-Agentなどがあります。
保存済みのCookieが送信条件に一致すると、ブラウザはCookieヘッダーも付けます。
次は、session_idという名前のCookieを送る説明用の例です。
Cookie: session_id=abc123
メッセージボディ
POST、PUT、PATCHなどでは、フォームの入力値やJSONなどをメッセージボディとして送ることがあります。
次は、利用者名とパスワードをJSON形式で送る説明用の例です。
POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 42
{"username":"user01","password":"example"}
Content-Typeはボディのデータ形式を伝えます。
この例のContent-Length: 42は、ボディが42バイトであることを示しています。
正確にはオクテット(8ビット)単位の長さであり、日本語などを含む場合の文字数とは一致しません。
ここではJSONの末尾に改行を含めていません。
HTTP/1.1でリクエストボディを送るには、受信側がボディの終わりを判別できるようにします。
上の例ではContent-Lengthで長さを示していますが、Transfer-Encoding: chunkedを使ってデータを区切って送る方法もあります。
この2つのヘッダーは、同じメッセージで併用しません。
HTTPレスポンスの中身
サーバーはリクエストを処理した結果をHTTPレスポンスとして返します。
次は、GET /aboutに対してHTMLを返すHTTP/1.1の例です。説明に必要なヘッダーだけを掲載しています。
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 72
<!doctype html><html lang="en"><title>About</title><h1>About</h1></html>
先頭はステータス行で、HTTPのバージョン、ステータスコード、短い説明を並べています。 続くヘッダーの後に空行があり、その後がHTMLのボディです。 この例のボディは、末尾の改行を含めず72バイトです。
ステータスコード
ステータスコードは、リクエストの処理結果を3桁の数値で表します。 クライアントはこれを見て、成功したのか、別のURLへのアクセスが必要なのか、エラーが発生したのかを判断します。
| ステータスコード | 意味 |
|---|---|
200 OK | リクエストが成功した |
204 No Content | 処理は成功したが、返すコンテンツはない |
301 Moved Permanently | リソースに新しい恒久的なURLが割り当てられた |
404 Not Found | リソースが見つからない、またはサーバーがその存在を明かさない |
500 Internal Server Error | サーバーで予期しない問題が発生し、要求を処理できなかった |
301などのリダイレクトでは、移動先のURLを通常はLocationヘッダーで伝えます。
ステータスコードは結果の種類を示し、ヘッダーは次の処理に必要な情報を補います。
レスポンスヘッダー
レスポンスのヘッダーには、データ形式のほか、キャッシュやCookieに関する情報などを含めます。 キャッシュとは、受け取ったデータを保存して、後で再利用する仕組みです。 次は、レスポンスヘッダーの一部を抜き出した例です。
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Set-Cookie: session_id=abc123; Secure; HttpOnly
Cache-Control: no-cacheは、保存したレスポンスを再利用する前に、元のサーバーで有効性を検証する必要があることを示します。
保存自体を禁止する指定はno-storeです。
Set-Cookieは、ブラウザへCookieの保存を指示するヘッダーです。
ブラウザはCookieの属性や自身の設定・ポリシーに従って保存を判断します。
SecureやHttpOnlyなどの属性は、Cookie(クッキー)の解説で扱っています。
メッセージボディ
レスポンスのボディは、クライアントへ返すデータ本体です。
ページの取得ならHTML、APIの呼び出しならJSONなどが入ります。
ただし、すべてのレスポンスにボディがあるわけではなく、例えば204 No Contentにはボディを含めません。
Cookie・セッションとの関係
HTTPはステートレスなプロトコルです。これは、HTTP自体が利用者のログイン状態などをリクエスト間で記憶する仕組みを持たないことを意味します。 同じ接続で通信を続けていても、それだけでログイン状態を管理できるわけではありません。
複数のリクエストにまたがってログイン状態を扱う場合は、Cookieやセッションなどを組み合わせます。 一般的なサーバー側のセッション管理では、ブラウザがセッションIDをCookieで送り、WebアプリケーションがそのIDに対応する状態をサーバー側の保存先から取り出します。
Cookieは値を保存して送信する仕組みで、セッションは利用者ごとの状態を管理する仕組みです。
IDの照合や有効期限については、セッション(Session)の解説を参照してください。
この記事のabc123は説明用の値であり、実際の認証用セッションIDには推測されにくい値を使います。
HTTPSでも基本的なやり取りは同じ
HTTPSでも、クライアントがHTTPリクエストを送り、サーバーがHTTPレスポンスを返すという関係は変わりません。 HTTPSはTLSの仕組みによって、HTTPヘッダーやボディなどを、通信経路上での盗み見や改ざんから保護します。
先ほどのログイン例も、実際にパスワードを送る際はHTTPSで通信します。
POSTを使ったり、ボディにデータを入れたりするだけでは、通信は暗号化されません。
HTTP/1.1・HTTP/2・HTTP/3の違い
この記事では、構造を読み取りやすいHTTP/1.1のメッセージを例にしています。 HTTP/2やHTTP/3でも、メソッド、ステータスコード、ヘッダー、コンテンツといった基本的な意味は共通です。
一方、ネットワーク上での表現方法は異なります。
HTTP/2ではメッセージをバイナリ形式のフレームに分けて送り、HTTP/3ではQUICという通信プロトコル上のストリームでフレームを送ります。
HTTP/2やHTTP/3で、GET /about HTTP/1.1のような行がそのまま送られるわけではありません。
ブラウザの開発者ツールで確認する
実際のリクエストとレスポンスは、ブラウザの開発者ツールから確認できます。 Chromeでは、次の手順でページ表示時の通信を調べられます。
- Webページを開き、ブラウザの開発者ツールを開く
Network(ネットワーク)パネルを選ぶ- ページを再読み込みする
- 一覧からHTML、CSS、画像、APIなどのリクエストを選ぶ
HeadersでURL・メソッド・ステータスコード・ヘッダーを、Responseでレスポンスの内容を見る
まずHTMLの取得を選んで、リクエストのGETとレスポンスの200などを見比べると、要求と結果の対応が分かります。
データを送信するリクエストでは、Payloadから送信内容も確認できます。
開発者ツールは解析した情報を表示するため、HTTP/2やHTTP/3でもヘッダーを読みやすい形で確認できます。
参考資料
- RFC 9110: HTTP Semantics — メソッド、ステータスコード、ヘッダー、HTTPS
- RFC 9112: HTTP/1.1 — メッセージ形式、リクエスト対象、ボディの長さ
- RFC 9111: HTTP Caching —
no-cacheとno-store - RFC 5789: PATCH Method for HTTP
- RFC 6265: HTTP State Management Mechanism —
CookieとSet-Cookieの基本 - RFC 9113: HTTP/2
- RFC 9114: HTTP/3
- Chrome DevTools: Network features reference