あきれるほど簡単なHTTP入門
この記事の目的
本記事では表題の通り、HTTPの解説を行います。
ですが深掘りはしません。あくまでもHTTPの全容を眺めるのが目的です。
-
普段の開発で何気なく使っているけどHTTPが何をしているのかわからない人
-
HTTPの勉強をしているけどいまいち全容が掴めない人
そんな人に読んでいただき、少しでもHTTPについての理解を深めていただきたいと思います。
HTTPの役割
HTTPという名前の意味
HTTPが何の略なのか知っている人は結構多いと思いますが、改めて説明しますとHyper Text Transport Protocolです。つまり「ハイパーテキストを伝送するためのプロトコル(規約)」ですね。
同じWeb関連のキーワードでHTがつくものといえばHTMLですが、こちらもHyper Text Markup Languageで、同じく「ハイパーテキスト」と言うキーワードが含まれています。
何を隠そう、HTTPはHTMLを送ったり受け取ったりするためのプロトコルなのです。元々は研究論文などを研究所間で共有するために使われていました。
それが今ではだいぶ拡張されて画像ファイルやCSSファイル、JavaScriptファイルなどを伝送するのにも使われているわけです。(現実に則するなら Web Resource Transport Protocol にでも改名すべきですね)
HTTPの歴史はWikiなんかに簡単な紹介が載っているので、気になる方はご一読どうぞ。
現在のHTTPの立ち位置としては「Web技術においてデータの送受信を担う仕組み」といったところになります。
どうでしょう、改めて言われればそりゃそうだよなって感じでしょうか。自分も同感です。
プロトコルは役割の話である
ではデータをやり取りするだけのプロトコルが、なぜこれほどまでに重要視されているのでしょうか。
インターネットのプロトコル群にはそれぞれ役割があります。
IPは通信社間でお互いを認識するために使われますし、TCPは相互に信頼性の高い通信を実現するためにあります。
プロトコルの役割が分かればプロトコルの理解も早く進みます。
ではHTTPの役割に焦点を当ててみていきましょう。
データ送信以上の役割
HTTPはその仕様のシンプルさ(後述)にもかかわらず、今日までさまざまな機能が追加され、Webを支える主要技術になりました。
しかしHTTPのおおもとがデータ送信のためのプロトコルであることは今も変わりはありません。
HTTPが他の通信プロトコルと異なるのは、よりデータの中身に関心を持ったプロトコルであるという点です。
はじめこそはHTMLしか扱えませんでしたが、今日では画像やJavaScriptファイルなど、様々なフォーマットのデータを扱うことができます。
ほかのプロトコル(例えばTCPなど)が「どれくらいのサイズのデータを送るか」くらいしか関心がないのに対し、HTTPは「どんなデータをどんなふうに送るか」まで気遣います。
この中身に重点をおいた仕様が、アプリケーションにとってはとても都合がいいのです。
アプリケーションにおけるHTTP
アプリケーションにおいて、ユーザーはサーバーからただ一方的にコンテンツを受け取るだけではありません。
ユーザーもまたサーバーに対してデータを送ります。
認証情報(メールアドレスやパスワードなど)や使用しているブラウザの情報、アップロードしたファイルなどがHTTPを介してサーバーに送り届けられます。
もしHTTPがなかったとしたら、サーバーはこれらのデータをどのように扱えばよいか判断できません。
テキスト情報を待ち受けているところに画像が送られたとしても、サーバーは気づかずに画像をテキストファイルとして解釈しようとするでしょう。
そしてあなたのプロフィール紹介欄に意味不明な文字の羅列が刻まれます...。
どうでしょうか。だんだんとHTTPの役割がどんなものかイメージができてきたでしょうか。
ここまでの内容を念頭に置いたうえで、次はHTTPの仕組みの話に行きましょう。
HTTPの構成要素
今回はHTTPの蓋然的な理解を目的としていますので、ここの構成要素について深くは掘り下げません。
ですが実際の開発に際しては、これから紹介する要素についてちゃんと理解する必要があります。
リクエストとレスポンス
詳細に入る前にまず前提の話をします。
HTTPの通信には必ず2人の登場人物がいます。
一人はコンテンツや特定の処理を要求するリクエスト(Request)、もう一人は要求に対して応答を返すレスポンス(Respons)です。
間違いを恐れずに言ってしまうと、HTTP通信とは「お願いします」と「はい、どうぞ」の繰り返しなのです。
リクエストを送る側は一般的にクライアントと呼ばれます。それに対し、応答する側はサーバーと呼ばれます。
よくレストランが例に出されますが、お客さん(クライアント)が「この料理をお願いします」と給仕の人(サービスを提供する人=サーバー)に頼んで料理(コンテンツ)が運ばれてくる状況はそのままクライアントとサーバーの関係に対応します。
メッセージの中身
「プロトコル」と聞くと小難しい内容を想像してしまいがちですが、HTTPの内容を構成する要素は以下のたった2つしかありません。
- ヘッダー部(Head)
- コンテンツ(Body)
以下はHTTPメッセージの例です。
GET / HTTP/1.1 --┐
Content-Type: text/html |-- ヘッダー部
Connection: keep-alive |
... --┘
--- (空行)
<!DOCTYPE html> リクエスト/レスポンス内容
<html> ↓
....
ヘッダー部とボディの間の空行は「こっからしたがボディだよ」という目印です。
HTTPはこれら2つの要素だけで成り立っています。
頭と体だけというドラ〇もん並みの単純さです。
普段使っているアプリケーションがこんな単純な方法で外のサーバーとやり取りしていることを考えると、案外大したことないんだなと思えてきませんか。(失礼)
てっぺんの部分
ここからはここの構成要素についてみていきましょう。
まずはメッセージの一番頭にくっついていた部分についてです。
この部分ですね。
GET / HTTP/1.1
この部分はリクエスト側(クライアント)とレスポンス側(サーバー)で記述が異なりますが、それぞれの役割を念頭に置けばとても単純です。
まずはリクエスト側から見ていきましょう。
レスポンス側のてっぺん
いちばん左(GET
の部分)はリクエストの方法(メソッド)についての記述です。
メソッドにはいくつかの種類がありますが、これもまたHTTP自身と同じく単純な作りになっています。
代表的なものをいくつか紹介します。
- GET : 「これちょうだい」
- POST : 「これ受け取って」
- HEAD : 「ヘッダー部分をを送れ」
- DELETE : 「これ消して」
見ればわかるようにこれはリクエストで何を求めているのかを表現しています。
真ん中の部分(/
)は求めるコンテンツがある場所を指します。
例えばexample.com
の一番上の階層にあるHTMLを要求するときなどに/
と表現します。
最後の部分(HTTP/1.1
)は見ての通りHTTPのバージョンです。
ここでHTTPで通信する際のHTTPバージョンを要求しています。
要求したバージョンによってはサーバーがサポートしていなかったり、あえて拒否されたりもします。
レスポンス側のてっぺん
次にレスポンス側のてっぺん部分ですが、以下のような記述になります。
HTTP/1.1 200 OK
レスポンスの場合はリクエストの時よりも単純になります。基本的に真ん中の部分を見ればサーバーがリクエストをどのように処理したかがわかるからです。
「HTTP/1.1
」の部分はリクエストの時と同じくHTTPのバージョンを指します。
意味としては「~のバージョンのHTTPでリクエストされました」程度の意味です。
重要なのは先ほども言った通り、次の真ん中の部分です。
これはステータスコード(Status Code)と呼ばれ、サーバーの応答結果を表します。
次の「OK
」の部分はステータスコードに付随する具体的なメッセージに過ぎず、実際あってもなくてもよいものです。
ステータスコードは3桁目の数字を境に大まかな意味が決められています。
- 100~ : 「情報」
- 200~ : 「成功」
- 300~ : 「リダイレクト(別の場所に誘導する)」
- 400~ : 「不正なリクエスト」
- 500~ : 「サーバーのエラー」
それぞれのコードの具体的な意味はここでは省きますが、代表的なものに
- 301 : コンテンツが別の場所に移動された
- 404 : コンテンツが存在しない
- 505 : 指定されたHTTPのバージョンに対応していない
などがあります。
なお、公式に規定されているステータスコード以外のものであれば実装者が自由に定義できます。(ただしブラウザはそのステータスコードの意味を理解できません)
ヘッダー
てっぺんの下から空行までの部分はクライアントとサーバーの具体的なやり取りのために用いられます。
GET / HTTP/1.1
Content-Type: text/html --┐
Connection: keep-alive |--ここ
... --┘
<!DOCTYPE html>
<html>
....
例えばConnection: keep-alive
は「レスポンスが返ってきた後も接続を継続してください」という意味です。
クライアントとサーバーで同じようなヘッダーもありますが、基本的には別々のヘッダーを使います。
クライアント側のヘッダーはリクエストヘッダー、サーバー側のヘッダーはレスポンスヘッダーといいます。
リクエストヘッダー
リクエストヘッダーではサーバーに対する要求が主になります。
よく使われるものを例に挙げると
-
Host
: ドメインを指定する -
Accept
: 要求するファイルの形式を指定する -
Accept-Encoding
: コンテンツの圧縮方法を指定する
などがあります。
ほかにもブラウザの情報を伝えるための**User-Agent
ヘッダー、クッキー情報を渡すためのCookie
**ヘッダーなどがあります。
レスポンスヘッダー
リクエストヘッダがサーバーに対する要求を投げていたのに対し、レスポンスヘッダーはクライアントへの応答結果と指示を行います。
いくつか例を挙げます。
-
Content-Encoding
: コンテンツの圧縮した際の方法を伝える -
Server
: レスポンスをしたWebサーバー名 -
Set-Cookie
: ブラウザにクッキー情報を保存するように伝達
HTTP通信がクライアントの要求とサーバーの応答で成り立っているという公式はヘッダーにおいても変わりません。
ヘッダーへの理解はアプリケーション開発の際にも重要になりますので、わからないヘッダーがあれば調べてみることをお勧めします。
ボディ
最後にボディ部分ですが、ここはリクエストとレスポンスの間で違いはありません。
具体的なデータを乗っける場所ですから、当たり前っちゃ当たり前です。
ボディを利用する場合はContent-Type
ヘッダーにボディのデータ形式を記述します。そうしないと受け取った側はデータをどのように扱えばよいか判断できません。
まとめ
HTTPは最初こそ難しそうで勉強するのがおっくうに感じられますが、実際はそれほど複雑なことはしていないことがわかっていただけたでしょうか。
要求と応答、これがキーコンセプトです。このコンセプトを忘れずに学んでいけば、訳が分からなくなることはまずないでしょう。
HTTPの構成要素も単純で、ヘッダーとボディの2つだけです。通信相手とやり取りするときはヘッダーを利用し、データを送り必要があるときはボディに乗っけます。これだけ。
大まかなことが分かれば後は知らない部分を埋めていくだけです。
MDNなどにも日本語の情報はたくさんありますし、書籍も良書がたくさんあります。
ぜひ頑張って勉強してみてください。
Discussion