Webブラウザって何をしているの？

## 通信の仕組みを知らなくてもWebアプリは作れちゃうけど...
Webアプリケーションフレームワークを使用すれば、Webブラウザ（Webクライアント）とWebサーバの通信の仕組みを知らなくても、一応動くWebアプリケーションを作ることができますよね。

しかし通信の仕組みを知っていないと、何か問題が発生した時に原因の特定が手探りになり、解決に多くの時間を浪費してしまうかもしれません。Webアプリケーションの規模が大きくなり、システム利用者が増えてくると、障害発生により多大な損害が出てしまうこともありますよね。

障害は発生させないことが望ましいですが、発生後すぐに解決することも同じように大切だと思います。原因特定を迅速に行うためにも、通信の仕組みをちゃんと理解してた方がよいかもしれません。

## これは何の記事か？
プログラミングしか学んでこなかったエンジニアが本を参考に、Webブラウザがどういった役割を担っているのかついてまとめた記事です。

**対象読者**

- プログラミングしか学んでこなかった
- HTTPについての理解が曖昧である

## この記事のゴール
- Webサーバとの通信において、Webブラウザがどういった役割を担っているかを把握できる

## Webブラウザって何をしているの？
WebブラウザとWebサーバが通信を行うときは、基本的にWebブラウザからリクエストを送って、それを受け取ったWebサーバがレスポンスを返すという仕組みになっています。

そこで、通信の始まりとなるWebブラウザが一体どういった役割を担っているのかについて説明します。

### 全体像の把握
WebブラウザがWebサーバへ向けてデータを送信するときは、 **OSI参照モデル** のアプリケーション層から物理層に向けて処理が行われ、逆にWebサーバがWebブラウザからのデータを受信するときは **OSI参照モデル** の物理層からアプリケーション層に向けて処理が行われます。

![osi_reference_model.png](https://qiita-image-store.s3.amazonaws.com/0/186009/0783f51c-94cc-03ee-30db-e41a40b8a031.png)

この記事は、WebブラウザがWebサーバに対してデータを送信するときの、アプリケーション層からセッション層で行われる処理についてまとめたものになります。（赤枠の部分）

### HTTPって何？
**HTTP（HyperText Transfer Protocol）**を一言で説明することが（個人的に）難しいのですが、Webブラウザ（Webクライアント）とWebサーバがHTMLデータを送受信するときに、そのデータを通信に適した形にするためのルールをまとめたものと解釈しました。

※ HTTPに則って整形されたデータが、下位の層のプロトコルであるTCP/IPなどに則って送信されます。

### URLからアクセス先を解読
まずはWebブラウザの最初の仕事について、説明します。

WebブラウザにURLを入力すると、まずWebブラウザはURLを解読します。

```console:例
http://www.example.com/dir/file1.html
```

上記のURLがWebブラウザに入力された場合、WebブラウザはHTTPに則って `www.example.com` というドメイン名のWebサーバにある `/dir/file1.html` というファイルにアクセスするというように解読します。

HTTPにおけるURLのフォーマットは以下のように決まっているので、WebブラウザはURLを解読できるわけです。

![http_url_format.png](https://qiita-image-store.s3.amazonaws.com/0/186009/206a46e2-0d64-ca54-2c87-0bd658f24ceb.png)


### Webサーバへのリクエスト・メッセージを作成
ここから、WebブラウザがWebサーバへ送信しようとしているデータが、どのようにして通信に適した形に整形されるのかについてまとめていきます。

URLを解読すればどこにアクセスするべきかがわかるので、次はWebサーバに対して送信するリクエスト・メッセージを作成します。

このリクエスト・メッセージが送信されると、Webサーバがそれを解読して、処理を行い、レスポンス・メッセージをWebブラウザに送り返すことで、通信ができるわけです。

ではリクエスト・メッセージがどのように作られているのかを説明します。リクエスト・メッセージもHTTPによりフォーマットが決まっているので、Webブラウザはそれに則ってリクエスト・メッセージを作成します。

![request_message.png](https://qiita-image-store.s3.amazonaws.com/0/186009/afe809d7-09cb-8649-cae5-0b8e35a25c58.png)

#### リクエスト・ライン
1行目はリクエスト・ラインと呼ばれ、空白で区切られた**メソッド**・**URI**・**HTTPバーション**という3つ要素に分けられます。ここを見ればリクエストの大体の内容を把握することができます。

- **メソッド**
    - リクエストの種類を表します。GETメソッドの場合は、「URIで指定した情報を送ってください」という意味になります。他にも POST や PATCH, DELETEといったメソッドがあります。

- **URI**
    - GETメソッドだけだと、「情報をください」という意味にしかなりません。そこで、インターネット上のどの情報なのかを指定するのが**URI（Uniform Resource Identifier）**です。

- **HTTPバージョン**
    - HTTPのバージョンを表します。バージョンによって利用できるメソッドやリクエスト・ヘッダーの情報が変わってくるので、バージョンを指定する必要があります。

#### メッセージ・ヘッダー
2行目以降で空白行よりも前の部分を**メッセージ・ヘッダー**と呼び、`Accept`、`Accept-Language`といった様々な情報があります。今回は割愛させていただきます。

#### メッセージ・ボディ
メッセージ・ヘッダーよりも後ろの部分を**メッセージ・ボディ**と呼びます。POSTメソッドなどでデータを送信するときは、入力したデータがここに記載されます。


### WebサーバのIPアドレスを特定
リクエスト・メッセージ内では、どの情報にアクセスするかを**URI**によって指定していますが、作成したリクエスト・メッセージをOSに送信してもらうときは、宛先としてドメイン名ではなく**IPアドレス**を指定しなければなりません。

そこで**URI**に記述されたドメイン名をIPアドレスに変換する仕組みとして**DNS（Domain Name System）**というものがあるのですが、これはトランスポート層の**UDP（User Datagram Protocol）**が関連する場所なので[別の記事](https://qiita.com/tamago3keran/items/eb5c1bd56a3927382c09)でまとめようと思います。

現段階では、リクエスト・メッセージがWebサーバに送られる前に、URIに書かれているドメインがIPアドレスに変換されるということだけ把握していてください。


### TCP/IPによってリクエスト・メッセージがWebサーバに送られる
これまでのHTTPに則った処理によって、データ（リクエスト・メッセージ）が通信に適した形に整形されました。

あとはOSのプロトコル・スタックに依頼して、整形したデータをTCP/IPに則ってWebサーバへ送信してもらいます。TCP/IPの仕組みについては、また別の記事で説明します。

## まとめ
WebブラウザはWebサーバとの通信において、**HTTPに則ってURLを解読し、データ通信に適したリクエスト・メッセージを作成する**という役割を担っている。

## 参考にした本
- [「プロになるためのWeb技術入門」 ― なぜ、あなたはWebシステムを開発できないのか](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352)
- [イラスト図解式 この一冊で全部わかるサーバーの基本](https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E5%9B%B3%E8%A7%A3%E5%BC%8F-%E3%81%93%E3%81%AE%E4%B8%80%E5%86%8A%E3%81%A7%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E5%9F%BA%E6%9C%AC-%E3%81%8D%E3%81%AF%E3%81%97-%E3%81%BE%E3%81%95%E3%81%B2%E3%82%8D-ebook/dp/B01DBQQ80A)
- [ネットワークはなぜつながるのか 第２版](https://www.amazon.co.jp/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8B%E3%81%AE%E3%81%8B-%E7%AC%AC%EF%BC%92%E7%89%88-%E6%88%B8%E6%A0%B9-%E5%8B%A4-ebook/dp/B077XSB8BS)

## 所感
HTTPやTCP/IPの仕組みを知らなくても、正直Webアプリケーションフレームワークを使って開発してしまえば、動くものを簡単に作れてしまいます。私も Ruby on Rails を使って開発をしていますが、HTTPやTCP/IPについてはなんとなくでしか理解できていませんでした。

今回改めてHTTPについて学んだことで、HTTPとTCP/IPが適用される部分の境界線やOSI参照モデルとの関係などが明確になり、Webアプリケーションにおける基礎知識が定着したように感じています。

次はUDPとDNSの仕組みについてまとめます。