HTTPってなんだ

WEBの勉強を始めてからものすごく感じることとしては、**HTTPというプロトコルの完成度の高さ**でした。
まだまだ勉強不足で、とにかく浅い内容になってしまいそうですが、HTTPについて簡単にまとめていこうと思います。

# HTTPの意味
HTTPとは、**Hypertext Transfer Protocol**の略で**WEB上でクライアントとサーバーがリソースのやりとりをするためのプロトコル**のことです。

ここで、それぞれの言葉を簡単に説明すると…

* クライアント　＝　スマホやPCなど、Webに接続し能動的にデータを取ろうとする端末（厳密に言うとブラウザ自身）
* サーバー　＝　クライアントにデータを提供する機器
* リソース　＝　HTMLファイルなどの提供される実データ
* プロトコル　＝　事前に取り決めておく約束事のこと

こんな感じかなと思います。

要は、**WEBページの閲覧なんかをするときにスマホやPCとWEBサーバーの間で、『このページを見たいなら、ちゃんとHTTPというルールに則って通信してね』という事前の取り決めごと**のことをHTTPと言います。
※かなり端的って言っています※

## HTTPはどんな時に使われるの？
HTTPは、名称に『Hyper Text』とある通り、**主に『HTML(Hyper Text Markup Language)ファイル』のやり取りを行う際**に用いられます。

ものすごく端的に言うとHTMLファイルはWEBページの元データのことです。このHTMLファイルをブラウザが読み込んで、WEBページとして表示してくれます

ハイパーテキストとは、その名の通り「**テキストを超えたテキスト**」という意味です。

もう少し詳細を説明すると、「**複数のファイル(リソース)同士をリンク付けする仕組み**」のことを言います。
※ハイパーテキストを作成するための言語がHTMLなどで、リンク付けされた状態のことを「ハイパーリンク」と呼称しています。

また、**複数のリソースが相互に結びつくことによって、Webという世界が構築されています**。

色々と説明を重ねてしまいましたが、要は**HTTPはWEB上で(主に)WEBページを取得する際に用いられるもの**と言えます。

# HTTP通信の流れ
ここからは実際のHTTPの通信の流れを簡単にまとめていきます。

HTTP通信は「**クライアントからのリクエスト、サーバーからのレスポンス**」という流れが基本になってきます。
1. クライアントが「WEBページを見せてください」とサーバーへリクエスト
2. サーバーがレスポンスをしてくれるまでクライアントは待機
3. サーバーがクライアントへ「いいよ〜 or だめだよ〜」とレスポンス
4. 他に必要なもの（WEBページ上の画像など）があれば再度リクエストを実施

![reqres.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/d6bee7cb-6f78-d931-51c1-13f027619c3c.png)


上記の通り、リクエスト→レスポンス→リクエストを繰り返してWEBページの表示を行います。
ここからはちょっとややこしい話になりますが、実際に**クライアントがどのようなリクエスト**を送って、**サーバーがどのようなレスポンスを返す**のかを見ていきます。

## クライアントのリクエスト
『Yahoo!』のトップページに接続した際のHTTPリクエストの内容は以下の通りです。
余談ですが、HTTPリクエストやレスポンスの内容はロームの拡張機能である『Live HTTP header』などを用いると便利です。

```http:リクエスト
GET / HTTP/1.1
Host: www.yahoo.co.jp:443
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
sec-ch-ua-mobile: 0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
```

色々とごちゃごちゃ書かれていてややこしいのですが、ざっくりと説明していきますね。


### リクエストライン
まずは一行目と二行目についてです。
一行目は**リクエストライン**と呼ばれていて、『**メソッド / URI / プロトコルバージョン**』という文法で成り立っています。
二行目のHOSTで書かれた接続先で、一行目に書かれたURI階層に接続するという意味になります。
ごめんなさい、ややこしいですね。例を見てみましょう。

例えば、以下はYahoo!のニュース面に接続した際のリクエストラインです。
接続したURIは『https://news.yahoo.co.jp/categories/sports 』です。

```http:リクエストラインの例
POST /categories/sports HTTP/1.1
Host: news.yahoo.co.jp:443
```

次はメソッドがGETからPOSTに変わってしまっていますが、ここは一旦無視してください()。
上記のHOST部は『**news.yahoo.co.jp**』となっており、一行目のURI部は『**/categories/sports**』となっています。
従って、上記は『**news.yahoo.co.jpというURIの/categories/sports階層をリクエスト**』となります。
※もちろん一行目で絶対パス指定も可能です

ということで最初のリクエストラインに戻りますと…
下記は、
『**GETというメソッドで、www.yahoo.co.jpのルートディレクトリ（/のみなので）にHTTP/1.1というプロトコルバージョンでリクエストします**』
という意味になります。

```http:GET
GET / HTTP/1.1
Host: www.yahoo.co.jp:443
```

### ヘッダ部
二行目以降、すなわちリクエストラインよりも後の行については「**ヘッダ部**」と呼ばれ、細々とした設定などが記述されています。
基本的には『**名前：値**』という形式で記載されます。
そのため、『HOST : www.yahoo.co.jp :443』と記載されれば、**HOSTにはwww.yahoo.co.jp と443というポート番号**が設定されます。

ヘッダの値は色々ありますので、気になった方は調べてみてください（放棄）

ちなみにヘッダの後に実質的なデータを記載する『**ボディ部**』という場所もあるのですが、今回のリクエストでは現れませんでした。
とりあえずボディ部というものもあるということだけご認識いただければと思います。

### GETとPOST
さきほどのリクエストラインの説明で出てきた「**GET**」と「**POST**」について簡単に説明していきます。
語弊を恐れずに簡潔に言うと、

**GETは、URIの末尾にパラメータを付与してリクエストする方式**
で
**POSTは、ボディ部にパラメータを入れてリクエストする方式**
です。
※実際のところはPOSTには「リソースの作成」などの明確な用途があるため、上記だけが異なるわけではありません。
この点については、余力があればまた違う記事で…

GETを用いてリクエストするケースは、URIにパラメータが含まれても良い（可視化されても問題ない）ときに用います。
例えば、ECサイトで商品のカテゴリを指定した際は…
**『www.ex-ec-site.com/top?category="Shoes"』**
というようなURIになるとします。（?から後ろがパラメータです）

このカテゴリについては、別にURI上で表示されていても困らないですよね？カテゴリ情報程度であればセキュリティ的にも問題なさそうです。
※余談ですが、この場合のリクエストラインは以下が想定されます。

```http:GET
GET /top?category="Shoes" HTTP/1.1
Host: www.ex-ec-site.com
```

しかし、個人情報を打ち込む必要があるときはどうでしょうか？
例えば同様のECサイトで自身の住所を記載する際に以下のように表示されるのはセキュリティ的にもよくなさそうです。
なぜなら**URIさえ見れれば、住所が特定されてしまうから**です。
**『www.ex-ec-site.com/address?adrs="東京都港区〇〇□□✗✗"』**

そんなときは、以下のように**POSTを使ってパラメータをHTTPリクエストのボディ部に隠します**。

```http:POST
POST /address HTTP/1.1
Host: www.ex-ec-site.com

adrs = "東京都港区〇〇□□✗✗"
```
上記のようにすることで、URIに直打ちされることもなくなります。
また、POSTを用いることで地獄みたいに長いパラメータなどを指定する必要がある際も、URIをきれいなままで保つことができます。

## サーバーのレスポンス
リクエストに続いて、次は**サーバーのレスポンス**です。
今回最も大切なポイントは**一番上の行です**。

```http:Response
HTTP/1.1 200
accept-ranges: none
age: 0
cache-control: private, no-cache, no-store, must-revalidate
content-encoding: gzip
content-type: text/html; charset=UTF-8
date: Sat, 30 Apr 2022 23:39:19 GMT
expires: -1
pragma: no-cache
server: ATS
vary: Accept-Encoding
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-vcap-request-id: 3abe655b-7f59-4e49-583e-9520b9175811
x-xss-protection: 1; mode=block
```
リクエストに対して、以下のように返答があります。
これは**ステータスライン**と呼ばれ『**プロトコルバージョン / ステータスコード / テキストメッセージ**』という構成です。

```http:Response
HTTP/1.1 200
```
上記の場合は『**HTTP/1.1でリクエストされたものに対して、200というステータスを返します**』という意味になります。
後述しますが、200というステータスコードは『**リクエスト成功**』を意味しており、クライアントのリクエストは正常に終了したことを意味しています。
今回はテキストメッセージが記載されていませんでしたが、サーバーによっては『**HTTP/1.1 200 OK**』のようにメッセージを付与しているところもあります。

また、ステータスラインに続く行はリクエストメッセージの際とほぼ同様に『**ヘッダ部**』と『**ボディ部**』になります。

## HTTPのステータスコード
レスポンスのステータスラインに記載されるステータスコードについて大枠を紹介します。
以下の大枠をなんとなく覚えておけば「どんなステータスなのか」をひと目で理解することができます。

* 100番台：処理中
* 200番台：成功
* 300番台：リダイレクト
* 400番台：クライアント側のエラー
* 500番台：サーバー側のエラー

『**200-OK**』や『**404-Not Found**』なんかは有名ですよね。
すべてを紹介することはできないので、気になる方はぜひとも都度調べてみてください（放棄）。

ということで、今回はこんな感じです。
まだまだ勉強不足なのが露呈してしまっていますが、これから頑張って理解を深めていきます。

# 参考
以下の資料がかなり勉強になりました。
他にも良い書籍や情報があれば教えてください！！

**Webを支える技術―― HTTP，URI，HTML，そしてREST**

https://gihyo.jp/book/2010/978-4-7741-4204-3

**RFC2616**

https://triple-underscore.github.io/rfc-others/RFC2616-ja.html