Webにおけるネットワーク通信
Published at 2014-12-03
「ネットワークってなんだろう?」と考えたことはあるだろうか。前職でもプログラマとして働いていたものの、(恥ずかしながら)知識は皆無に近かったし、Webのフロントエンジニアとして舵を切った2年と5ヶ月前は、この手の話がフロントエンドに関わるとは思ってもいなかった。
HTTPだの、WebSocketだの、言葉は耳にするけど実態はよくわからない …という人も多いと思う。私自身も深く密着しているわけではないし、語るほど詳しいかと言われれば疑問符が残る。それでも、今までモヤモヤしていたところを少しでも晴らす手助けが出来ればと思い、今日はインターネットの世界で何が起こっているかについての記事を書きたい。
そもそもサーバーとは?
サーバーって一体何だろうと思っている人も多いのではないだろうか?手元のパソコン、iPhone、Androidといった クライアントからの要求を待ち、応答する役割を担っているのがサーバー である。応答するプログラムであれば端末の種別は問わないが、起動しっぱなしのパソコンと思ってもらえばわかりやすいかもしれない。
電話におけるサーバー
クライアントからの応答を待つ役割をするサーバーは、インターネットに限った話ではない。例えば電話でのやりとりに於いても、サーバーは存在する。
- 電話のかけ手が、番号を入力し発信する
- サーバーが入力された番号を探す
- 電話の受け手が受信する
- サーバーを介して通話を開始する
このように、家の置き電話や携帯電話があるだけでは通話は成立せず、通話が確立するまでや、その後の通話(音声データのやりとり)もサーバーを介して行われている。
Webにおけるサーバー
ブラウザにURLを入力し、表示されたWebページを閲覧するということは誰しもが当たり前のようにやっていることだが、実はここでもサーバーが一役買っている。
- 入力されたURLのサーバーに対し、ブラウザが接続要求をする
- サーバーが接続要求に対し、応答する(接続開始)
- ブラウザがURLに関するリソースの要求をする
- サーバーがリソース(HTML)を送信する
厳密に言えば、URLに対してブラウザが接続要求を実行するタイミングでDNS解決というURL(ホスト名)からIPアドレスへの変換が行われる。インターネットにおける端末間の通信には、お互いを一意に認識するデータとしてIPアドレスを知っている必要があるためだ。先程の電話の場合は、電話番号がその役割を果たしている。
このクライアントの要求を リクエスト 、サーバーからの応答を レスポンス という。
サーバーとクライアントのやりとり
Webページの表示するために、クライアントとサーバーがやりとりを行っていることがわかった。次にどのようなやりとりを行っているかを見てみよう。
やりとりの中にはルールが存在している。普段の生活で言えば、 日本語のような決まった言語でやりとりをする であったり、 面と向かって、または何かしらのツール上でメッセージの交換をする といったように、何かしら縛りがあるはずだ。
クライアントがサーバーとやりとりを行う際も、ある一定のルールの中でやりとりが行われる。このコンピュータが行うやりとりにおけるルールをプロトコルと言う。以下、Wikipediaより引用。
プロトコルまたはプロトコール(英語 protocol 英語発音: [ˈproutəˌkɔːl] プロウタコール、[ˈproutəˌkɔl] プロウタコル、フランス語 protocole フランス語発音: [prɔtɔkɔl] プロトコル)とは、複数の者が対象となる事項を確実に実行するための手順等について定めたもの。日本語では「規定」「議定書」「儀典」などと意訳される。もともとは人間同士のやりとりに関する用語としてのみ用いられていたが、近年では派生的に、情報工学分野でマシンやソフトウェア同士のやりとりに関する概念を指すためにも用いられるようになった。
インターネットにおけるプロトコル
プロトコルの中でも、特に通信に関するプロトコルは通信プロトコルと言う。そして昨今のインターネットにおいては、HTTP(Hypertext Transfer Protocol)が最も多くの割合を占めている。以下、Wikipediaより引用。
Hypertext Transfer Protocol(ハイパーテキスト・トランスファー・プロトコル、略称 HTTP)とは、WebブラウザとWebサーバの間でHTMLなどのコンテンツの送受信に用いられる通信プロトコルである。ハイパーテキスト転送プロトコルとも呼ばれる。
静的なWebサイト・動的なWebアプリケーションを問わず、この一定のルールの元でやりとりが行われ、ブラウザにデータが返却される。つまり、 サーバーとクライアントがHTTPというルール(プロトコル)のもとで、データのやりとりを行う ということになる。
HTTPはその名の通り、ハイパーテキスト(HTML)の転送を主な目的としているが、それ以外にも画像や音声等のバイナリを含めて、様々なデータを扱うことが出来る。
HTTPを含む、ネットワークプロトコルは何層かに分かれており、HTTPはアプリケーション層と呼ばれる上位レイヤにあたるが、レイヤに関しての詳細は割愛する。先程の「やりとり」がTCP/IPのような下位レイヤのルールの元行われていると思ってもらえれば良いと思う。
Webページで発生しているHTTPリクエスト
前述の Webにおけるサーバー の項で触れたが、HTTPでは1つのリクエストにつき、以下のようなやりとりを行っている。
- 入力されたURLのサーバーに対し、ブラウザが接続要求をする
- サーバーが接続要求に対し、応答する(接続開始)
- ブラウザがURLに関するリソースの要求をする
- サーバーがリソース(HTML)を送信する
このやりとりのうち、1~3のステップがHTTPの下位レイヤにあたるTCPで行われることを (TCP)3-Way Handshake という。
ブラウザにURLを入力してWebページを表示するために、クライアント(ブラウザ)がリクエストし、サーバーがレスポンスする。ブラウザにおけるURL入力やリンクの押下はページ表示における最初のリクエストにあたり、WebサーバーはHTMLを返却する。
<html>
<head>
<title>ページタイトル</title>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<div class='container'>
<img src='image.png'>
<img src='image.jpg'>
<img src='image.gif'>
</div>
<script src='jquery.min.js'></script>
<script src='app.min.js'></script>
</body>
</html>
サーバーからHTMLが返却され、ブラウザがそれを受け取って、やりとりが終わるわけではない。まず、ブラウザは返却されたHTMLを解析する。上記の例は何の変哲もないHTMLだが、幾つか外部リソースを必要とする指定がある。
<link rel='stylesheet' href='style.css'>
<img src='image.png'>
<img src='image.jpg'>
<img src='image.gif'>
<script src='jquery.min.js'></script>
<script src='app.min.js'></script>
これらの要素のhref
属性、及びsrc
属性には外部リソースの要求を指定する(外部リソースを指定する要素は他にも、<audio>
や<video>
、CSSファイル内のパス指定等、色々ある)。よって、ここから更に、HTTPリクエストが断続的に発生する。
光回線のようなブロードバンド、モバイル端末向けでは4G回線も普及し、私達を取り巻くネットワーク環境は以前よりも良くなったものの、ハードウェアの進化に比べれば遅く、そして不安定である。Webページの最適化の為にHTTPリクエストを減らすというアプローチは、かなり浸透してきたが、こうした環境も背景にあるだろう。人間にとっても、持ち運ぶ荷物が軽くて小さいものであれば、まとめて運ぶ方が効率的であるのと同じことだ。
HTTPリクエストの区別
HTTPリクエストには用途に応じたメソッド(種類)があり、HTTP/1.0で5種類、HTTP/1.1で8種類のメソッドが定義されている。最も多く使われるのが GET
、その次にPOST
がある。
GET
はその名の通り、指定のURIに応じたリソースを取得する際のリクエストであり、POST
は指定のURIにデータを送信するリクエストである。その他にもPUT
、DELETE
等があるが、実際にはGET
が殆どを占めている。ブラウザにURLを入力し、Webページを表示するのもGET
、HTML中の<img>
要素による画像の取得もGET
である。
HTTPリクエストの付加情報
GET
リクエストによるデータの取得も、<script src='...'></script>
によるJSファイルや、<img src='...'>
による画像ファイル、Ajaxで取得するJSONデータ等、形式は様々である。
ブラウザはこれらを一体どのように区別しているのか。この仕組みは、リクエストとレスポンスのデータに付与される ヘッダー という付加情報によって成り立っている。
受け取るデータの区別は、サーバーから返却されるデータに含まれる レスポンスヘッダー の Content-Type
というデータの種別を表す項目で、ブラウザが判断する。他にもデータのサイズ(Content-Length
)等が含まれる。
例えるなら、配達物の伝票にあたるだろう。伝票には配達物が何なのかであったり、それが壊れ物なのかどうかが記されているはずだ。
また、リクエストするデータに付与される リクエストヘッダー には、受け取ることが可能なデータの指定(Accept
/ Accept-Encoding
/ Accept-Language
)や自身が何者なのか(User-Agent
)等が、
ブラウザによって付与される。
まとめ
以上のようなことがHTTP通信の基本的な動作であり、我々がWebブラウザでページを閲覧してる裏側で行われている。ブラウザ閲覧している時、なかなかページが表示されずイライラしたことはないだろうか?それはこのHTTP通信の遅延といったような、ネットワークのパフォーマンスが影響していることになる。
普段はこれらのやりとりは当たり前のものとして気にすることはないかもしれない。しかし、複雑なWebアプリの開発現場や進化するWeb技術、パフォーマンスに取り組む中で、 Webがどのような仕組みで動いているかは間違いなく必要な知識 だと思う。そしてこれらの改善について検討することも、我々フロントエンドに従事する人間の責務になりえるのかもしれない。
Webに従事していれば職域に関わらず、覚えていて損のない知識だとも思うので、今後Webに携わる中で何かの足しになれば。