HTTPプロトコル:インターネットの基礎であり、ウェブ開発に不可欠な知識
Daniel Hayes
Full-Stack Engineer · Leapcell

HTTPプロトコル:インターネットの基礎であり、ウェブ開発に不可欠な知識
インターネットの世界において、HTTPプロトコルは間違いなく基本的なプロトコルであり、ウェブ開発分野における必須の知識です。特に、その最新バージョンであるHTTP/2は、広範な注目を集め、技術的なホットスポットとなっています。この記事では、HTTPプロトコルの歴史的な進化と設計思想を掘り下げ、読者がこの重要な技術を包括的に理解するのに役立ちます。
I. HTTP/0.9:インターネット通信の萌芽
HTTPは、TCP/IPプロトコルに基づくアプリケーション層プロトコルです。クライアントとサーバー間の通信フォーマットを規定することに重点を置いており、データパケットの伝送には関与しません。デフォルトではポート80を使用します。1991年にリリースされたHTTP/0.9バージョンは、HTTPプロトコルの最も初期のバージョンです。その設計は非常にシンプルで、GETという1つのコマンドしかありません。
GET /index.html
上記のコマンドの意味は、TCP接続が確立された後、クライアントがサーバーからウェブページindex.htmlを要求することです。プロトコルによると、サーバーはHTML形式の文字列のみを応答でき、他の形式では応答できません。例えば:
<html> <body>Hello World</body> </html>
サーバーが送信を完了すると、すぐにTCP接続を閉じます。このバージョンは単純ですが、HTTPプロトコルのその後の開発の基礎を築き、クライアントとサーバー間の単純な通信モードの確立を示しました。
II. HTTP/1.0:機能の初期拡張
1996年5月、HTTP/1.0バージョンがリリースされました。HTTP/0.9と比較して、その内容は大幅に増加し、インターネットの開発に重要な変化をもたらしました。
2.1 はじめに
- コンテンツ形式の多様化:HTTP/1.0では、あらゆる形式のコンテンツの送信が許可されます。これにより、インターネットはテキスト伝送に限定されなくなり、画像、ビデオ、バイナリファイルなどのさまざまな種類のデータをネットワーク経由で送信できるようになり、インターネットの多様な開発のための強固な基盤が築かれました。
- 豊富なインタラクティブコマンド:GETコマンドに加えて、POSTコマンドとHEADコマンドが導入されました。POSTコマンドは、ユーザー登録やログイン時に送信される情報など、サーバーにデータを送信するためによく使用されます。HEADコマンドは、実際のリソースコンテンツを返さずにリソースのメタ情報を取得するために主に使用されます。これらのコマンドの追加により、ブラウザとサーバー間のインタラクション方法が大幅に豊富になりました。
- リクエストおよびレスポンス形式の変更:各通信では、データ部分に加えて、ヘッダー情報(HTTPヘッダー)を含める必要があります。これは、リクエストのソース、クライアントのタイプ、受け入れ可能なデータ形式など、いくつかのメタデータを記述するために使用されます。さらに、ステータスコード、マルチ charset サポート、マルチパート送信、認証、キャッシュ、コンテンツエンコーディングなどの機能が追加されました。ステータスコードは、リクエストに対するサーバーの処理結果を示すために使用されます。たとえば、200はリクエストが成功したことを示し、404はリソースが見つからなかったことを示します。マルチ charset サポートにより、インターネット上のさまざまな言語でコンテンツを正しく表示できます。キャッシュ機能は、繰り返しのリクエストを減らし、アクセス速度を向上させます。
2.2 リクエスト形式
GET / HTTP/1.0
User - Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
HTTP/0.9バージョンと比較して、1.0バージョンのリクエスト形式は大幅に変更されました。最初の行はリクエストコマンドであり、プロトコルバージョン(HTTP/1.0)を最後に付加する必要があります。以下は、クライアントの状況を記述するために使用されるヘッダー情報の複数行です。 User-Agentフィールドは、クライアントのタイプとバージョンを識別し、Acceptフィールドは、クライアントが受け入れることができるデータ形式を宣言します。
2.3 レスポンス形式
HTTP/1.0 200 OK
Content - Type: text/plain
Content - Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last - Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
サーバーの応答形式は「ヘッダー情報+空白行(\r\n)+データ」です。その中で、最初の行は「プロトコルバージョン+ステータスコード+ステータス記述」です。ステータスコード200はリクエストが成功したことを示し、OKはステータス記述です。Content-Typeフィールドはデータのタイプを示し、Content-Lengthフィールドはデータの長さを示し、Expiresフィールドはリソースの有効期限を指定し、Last-Modifiedフィールドはリソースの最終変更時間を示し、Serverフィールドはサーバーのタイプとバージョンを識別します。
2.4 Content - Typeフィールド
HTTP/1.0バージョンでは、ヘッダー情報はASCIIコードでなければならず、後続のデータは任意の形式にすることができます。したがって、サーバーが応答するとき、Content-Typeフィールドを介してデータの形式をクライアントに伝える必要があります。 Content-Typeフィールドの一般的な値は次のとおりです。
- テキストタイプ:text/plain(プレーンテキスト)、text/html(HTMLドキュメント)、text/css(CSSスタイルシート)。
- 画像タイプ:image/jpeg(JPEG画像)、image/png(PNG画像)、image/svg+xml(SVGベクターグラフィック)。
- オーディオおよびビデオタイプ:audio/mp4(MP4オーディオ)、video/mp4(MP4ビデオ)。
- アプリケーションタイプ:application/javascript(JavaScriptスクリプト)、application/pdf(PDFドキュメント)、application/zip(ZIP圧縮ファイル)、application/atom+xml(Atom XMLドキュメント)。
これらのデータ型はまとめてMIMEタイプと呼ばれます。各値には、スラッシュで区切られたプライマリタイプとセカンダリタイプが含まれます。事前定義されたタイプに加えて、メーカーはカスタムタイプを定義することもできます。たとえば、application/vnd.debian.binary-package
は、送信されるデータがDebianシステムのバイナリデータパッケージであることを示します。 MIMEタイプは、セミコロンを使用して最後にパラメーターを追加することもできます。たとえば、Content-Type: text/html; charset=utf-8
は、送信されるデータがウェブページであり、エンコーディングがUTF-8であることを示します。クライアントがリクエストを行うとき、Acceptフィールドを使用して、受け入れることができるデータ形式を宣言できます。たとえば、Accept: */*
は、クライアントが任意の形式のデータを受け入れることができることを示します。 MIMEタイプは、HTTPプロトコルだけでなく、他の分野でも広く使用されています。たとえば、HTMLウェブページでは、<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
または<meta charset="utf-8" />
を介してページのエンコーディングとコンテンツタイプを指定できます。
2.5 Content - Encodingフィールド
送信されるデータは任意の形式にすることができるため、送信効率を向上させるために、送信前にデータを圧縮できます。 Content-Encodingフィールドは、データの圧縮方法を示すために使用されます。一般的な値は、gzip
、compress
、deflate
です。クライアントがリクエストを行うとき、Accept-Encodingフィールドを使用して、受け入れることができる圧縮方法を示します。たとえば、Accept-Encoding: gzip, deflate
です。
2.6 短所
HTTP/1.0バージョンの主な欠点は、各TCP接続が1つのリクエストしか送信できないことです。データが送信されると、接続は閉じられます。他のリソースを要求する必要がある場合は、新しい接続を確立する必要があります。新しいTCP接続を確立するコストは比較的高く、クライアントとサーバーは3方向ハンドシェイクを実行する必要があり、初期伝送速度が遅いため(スロースタート)、HTTP 1.0バージョンのパフォーマンスが低下します。ウェブページにロードされる外部リソースが増えるにつれて、この問題はより顕著になっています。この問題を解決するために、一部のブラウザはリクエストで非標準のConnectionフィールドを使用しました。
Connection: keep-alive
このフィールドは、他のリクエストを再利用できるように、サーバーがTCP接続を閉じないように要求します。サーバーもこのフィールドで応答する場合、クライアントまたはサーバーが積極的に接続を閉じるまで、再利用可能なTCP接続を確立できます。ただし、これは標準フィールドではなく、実装によって動作が異なる場合があるため、根本的な解決策ではありません。
III. HTTP/1.1:広く使用されている古典的なバージョン
1997年1月に、HTTP/1.1バージョンがリリースされました。これは1.0バージョンよりもわずか半年後です。HTTPプロトコルをさらに改善し、今日でも広く使用されているバージョンになりました。
3.1 永続的な接続
HTTP/1.1バージョンの最大の変更点は、永続的な接続の導入です。つまり、TCP接続はデフォルトで閉じられず、Connection: keep-alive
を宣言する必要なく、複数のリクエストで再利用できます。クライアントとサーバーは、相手がしばらく非アクティブになっていることに気付いたときに、接続を積極的に閉じることができます。ただし、標準的な方法は、クライアントが最後の要求でConnection: close
を送信し、サーバーにTCP接続を明示的に閉じるように要求することです。現在、ほとんどのブラウザでは、同じドメイン名に対して6つの永続的な接続を確立できます。これにより、HTTPプロトコルの効率が大幅に向上します。
3.2 パイプライン処理
HTTP/1.1バージョンでは、パイプライン処理メカニズムも導入されました。同じTCP接続で、クライアントは複数のリクエストを同時に送信できます。たとえば、クライアントが2つのリソースを要求する必要がある場合、以前の方法は、同じTCP接続で最初にリクエストAを送信し、サーバーの応答を待ってから、応答を受信した後でリクエストBを送信することでした。パイプライン処理メカニズムを使用すると、ブラウザはリクエストAとリクエストBを同時に送信できます。サーバーは順番にリクエストAに最初に応答し、完了後にリクエストBに応答しますが、この方法により、HTTPプロトコルの効率がさらに向上します。
3.3 Content - Lengthフィールド
HTTP/1.1バージョンでは、TCP接続は複数の応答を送信できます。したがって、どの応答にデータパケットが属するかを区別するメカニズムが必要です。Content-Lengthフィールドの機能は、この応答のデータの長さを宣言することです。例えば:
Content - Length: 3495
この行のコードは、この応答の長さが3495バイトであり、後続のバイトが次の応答に属していることをブラウザに伝えます。 1.0バージョンでは、サーバーがTCP接続を閉じたことを検出すると、ブラウザはすべてのデータパケットが受信されたことを認識していたため、Content-Lengthフィールドは必須ではありませんでした。 1.1バージョンでは、TCP接続を再利用できるため、さまざまな応答を区別するためにデータ長を明確にする必要があります。
3.4 チャンク転送エンコーディング
Content-Lengthフィールドを使用するための前提は、サーバーが応答を送信する前に、応答データの長さを知っている必要があることです。時間のかかる動的操作では、これはサーバーがすべての操作が完了するまでデータを送信するのを待つ必要があり、効率が低下することを意味します。この問題を解決するために、HTTP/1.1バージョンでは、Content-Lengthフィールドを使用せずに、「チャンク転送エンコーディング」を使用できることが規定されています。リクエストまたはレスポンスヘッダーにTransfer-Encodingフィールドがある限り、応答が未確定数のデータチャンクで構成されることを示します。例えば:
Transfer - Encoding: chunked
空でない各データチャンクの前に、このチャンクの長さを示す16進数値があります。最後に、サイズ0のチャンクは、この応答のデータが完全に送信されたことを示します。次に例を示します。
HTTP/1.1 200 OK
Content - Type: text/plain
Transfer - Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
3
con
8
sequence
0
このメソッドを使用すると、サーバーはデータが生成されるとすぐにデータを送信でき、「バッファモード」を「ストリームモード」に置き換え、データ伝送の効率を向上させることができます。
3.5 その他の機能
HTTP/1.1バージョンでは、PUT(リソースの更新に使用)、PATCH(リソースの部分的な更新に使用)、HEAD(GETと同様ですが、リソースコンテンツではなくヘッダー情報のみを返します)、OPTIONS(サーバーがサポートするリクエストメソッドなどの情報を取得するために使用)、DELETE(リソースの削除に使用)など、多くの動詞メソッドも追加されました。さらに、クライアント側のリクエストヘッダーにHostフィールドが追加されました。これは、サーバーのドメイン名を指定するために使用されます。例えば:
Host: www.example.com
Hostフィールドを使用すると、同じサーバー上の異なるウェブサイトにリクエストを送信でき、仮想ホストの台頭の基礎が築かれます。 Hostフィールドを介して、サーバーは異なるドメイン名に応じて異なるサービスを提供し、リソースの共有と分離を実現できます。
3.6 短所
HTTP/1.1バージョンではTCP接続の再利用が可能ですが、同じTCP接続では、すべてのデータ通信が順番に実行されます。サーバーは、1つの応答が完了した後でのみ次の応答を処理します。以前の応答が特に遅い場合、多くのリクエストがキューに入れられて待機します。これは、「Head-of-lineブロッキング」と呼ばれます。この問題を回避するには、現在、2つの方法しかありません。1つはリクエストの数を減らすことであり、もう1つは複数の永続的な接続を同時に開くことです。これにより、スクリプトとスタイルシートのマージ、CSSコードへの画像の埋め込み、ドメインシャーディングなど、多くのウェブページ最適化技術が出現しました。ただし、HTTPプロトコルがより適切に設計されていれば、これらの追加の努力は回避できた可能性があります。
IV. SPDYプロトコル:HTTP/2の前身
2009年、GoogleはHTTP/1.1の効率の低さの問題を解決することを主な目的として、自社開発のSPDYプロトコルを公開しました。 Chromeブラウザで実現可能であることが証明された後、SPDYプロトコルはHTTP/2の基礎として使用され、その主な機能はHTTP/2で継承されました。SPDYプロトコルは、ヘッダー情報の圧縮や多重化などのHTTPプロトコルの最適化を通じて、データ伝送の効率を向上させ、HTTP/2の開発に貴重な経験と技術的基盤を提供しました。
V. HTTP/2:効率的な次世代プロトコル
2015年、HTTP/2がリリースされました。標準委員会はサブバージョンをリリースする予定がないため、HTTP/2.0とは呼ばれていません。次の新しいバージョンはHTTP/3になります。 HTTP/2は、HTTPプロトコルの開発史上非常に重要であり、一連の注目すべき改善をもたらしました。
5.1 バイナリプロトコル
HTTP/1.1バージョンのヘッダー情報はテキスト(ASCIIエンコード)であり、データ本体はテキストまたはバイナリにすることができます。ただし、HTTP/2は完全にバイナリプロトコルです。ヘッダー情報とデータ本体はどちらもバイナリであり、まとめて「フレーム」と呼ばれ、ヘッダーフレームとデータフレームが含まれます。バイナリプロトコルの利点は、追加のフレームを定義できることです。 HTTP/2は10個近くのフレームを定義しており、将来の高度なアプリケーションのための優れた基盤を築いています。これらの機能がテキストを使用して実装された場合、データの解析は非常に面倒ですが、バイナリ解析の方がはるかに便利です。バイナリプロトコルは、データをより効率的に送受信および処理でき、プロトコルのパフォーマンスと柔軟性を向上させます。
5.2 多重化
HTTP/2はTCP接続を再利用します。 1つの接続では、クライアントとブラウザの両方が複数のリクエストまたは応答を同時に送信でき、順番に1つずつ対応する必要がないため、「Head-of-lineブロッキング」を回避できます。たとえば、TCP接続では、サーバーはリクエストAとリクエストBを同時に受信します。したがって、最初に応答するのはリクエストAです。処理プロセスに時間がかかることがわかった場合は、処理されたリクエストAの部分を送信し、リクエストBに応答します。完了後、リクエストAの残りの部分を送信します。この双方向およびリアルタイムの通信は多重化と呼ばれます。多重化テクノロジーにより、HTTP/2は同じ接続で複数のリクエストと応答を同時に処理できるため、伝送効率が大幅に向上します。
5.3 データストリーム
HTTP/2のデータパケットは順不同で送信されるため、同じ接続の連続するデータパケットは異なる応答に属している可能性があります。したがって、どの応答に属しているかを示すために、データパケットをマークする必要があります。 HTTP/2は、各リクエストまたは応答のすべてのデータパケットをデータストリームと呼びます。各データストリームには一意の番号があります。データパケットを送信するときは、どのデータストリームに属するかを区別するために、データストリームIDをマークする必要があります。さらに、クライアントから送信されたデータストリームには奇数番号のIDがあり、サーバーから送信されたデータストリームには偶数番号のIDがあることが規定されています。データストリームの送信が途中の場合、クライアントとサーバーの両方が信号(RST_STREAMフレーム)を送信して、このデータストリームをキャンセルできます。 HTTP/1.1バージョンでは、データストリームをキャンセルする唯一の方法はTCP接続を閉じることです。ただし、HTTP/2では、TCP接続が開いたままであり、他のリクエストで使用できることを保証しながら、特定のリクエストをキャンセルできます。クライアントは、データストリームの優先度を指定することもできます。優先度が高いほど、サーバーは早く応答します。データストリームの概念と関連メカニズムを通じて、HTTP/2はより柔軟で効率的なデータ伝送と管理を実現します。
5.4 ヘッダー圧縮
HTTPプロトコルはステートレスであり、すべての情報を各リクエストに添付する必要があります。したがって、CookieやUser-Agentなど、リクエストには多くのフィールドが繰り返されます。同じコンテンツを各リクエストに添付する必要があるため、多くの帯域幅が浪費され、速度に影響します。HTTP/2は、ヘッダー圧縮メカニズムを導入することでこれを最適化しました。一方、ヘッダー情報はgzipまたはcompressを使用して圧縮してから送信されます。一方、クライアントとサーバーの両方がヘッダー情報テーブルを保持します。すべてのフィールドはこのテーブルに格納され、インデックス番号が生成されます。将来的には、同じフィールドは再び送信されず、インデックス番号のみが送信されるため、速度が向上します。ヘッダー圧縮メカニズムは、データ伝送量を効果的に削減し、伝送効率を向上させます。
5.5 サーバープッシュ
HTTP/2を使用すると、サーバーはリクエストなしでリソースをクライアントに積極的に送信できます。これはサーバープッシュと呼ばれます。一般的なシナリオは、クライアントが多くの静的リソースを含むウェブページを要求する場合です。通常、クライアントはウェブページを受信し、HTMLソースコードを解析し、静的リソースを発見してから、静的リソースのリクエストを送信する必要があります。ただし、サーバーは、クライアントがウェブページを要求した後、静的リソースを要求する可能性が高いことを予測できるため、これらの静的リソースをウェブページとともにクライアントに積極的に送信します。サーバープッシュテクノロジーは、クライアントリクエストの数を減らし、ユーザーエクスペリエンスを向上させます。
HTTPプロトコルの開発の歴史は、継続的な進化と最適化のプロセスです。最初は単純なHTTP/0.9から、機能が豊富なHTTP/1.1、そして効率的なHTTP/2まで、各バージョンは以前のバージョンの問題に取り組み、パフォーマンスと機能を強化してきました。技術の継続的な開発により、将来のHTTP/3も楽しみであり、インターネット通信テクノロジーの進歩を推進し続けるでしょう。
Leapcell:ウェブホスティング、非同期タスク、Redis向けの次世代サーバーレスプラットフォーム
最後に、ウェブサービスのデプロイに最適なプラットフォームをお勧めします。Leapcell
1. 多言語サポート
- JavaScript、Python、Go、またはRustで開発します。
2. 無制限のプロジェクトを無料でデプロイ
- 使用量に対してのみ料金を支払います—リクエストも料金もありません。
3. 無敵のコスト効率
- アイドル料金なしで従量課金。
- 例:25ドルで、平均応答時間60ミリ秒で694万リクエストをサポートします。
4. 合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察のためのリアルタイムのメトリックとログ。
5. 楽なスケーラビリティと高いパフォーマンス
- 高い同時実行性を容易に処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロ—構築に集中するだけです。
Leapcell Twitter: https://x.com/LeapcellHQ