執筆の背景
先輩エンジニアと職場で雑談している際に、
「リクエストレスポンスの処理を詳しく教えて?」
と不意打ちで質問されたのですが、あまりいい感じで説明できなかったため少し深掘りしてみました。
ということで、リクエスト - レスポンスに関して解像度を上げて、ブラウザから送られたHTTPリクエストが最終的にどのようにレンダリングされるのかを詳しく見ていきます。
※あくまでwebブラウザ-webサーバーの通信を前提としています。
リクエスト - レスポンスの全体像
webのアーキテクチャには、クライアント/サーバモデルが採用されています。
そのため、webアプリケーションはクライアントがリクエストを送信し、サーバーがレスポンスを返却するという仕組みによって成り立っていますが、より具体的に見ると以下のような処理が行われています。
- クライアント(Webブラウザ)からのリクエスト送信
- DNSによる名前解決
- webサーバーのリクエスト受信、内部スクリプトの実行とレスポンスの返却。
- webブラウザがHTTPレスポンスを受け取り、レンダリングエンジンが解釈したドキュメントをブラウザ上に表示する
※他にももっと色々やってますが、大きな粒度でこんな感じかと。
それぞれの内容について少し詳しく見ていきます。
クライアント(Webブラウザ)からのリクエスト送信
webブラウザから以下のようなタイミングで、webサーバーに対してHTTPリクエストが送信されます。
- ブラウザのアドレスバーに何らかのURIを入力した際
- webページ上のリンクをクリックした際
- フォームで何らかの値を入力し、submitした際
...など。
ブラウザから送信されるHTTPリクエストには、以下のような内容が含まれます。
- HTTPリクエスト行
- 使用するHTTPメソッド、送信先のホスト、HTTPのバージョン情報
- リクエストヘッダ
- メディアタイプ
- 文字エンコーディングの方式
- 使用する言語
- その他メタ情報
- リクエストボディ
- POSTメソッド等で何らかの処理を要求する際に、パラメータを含める
参考:
DNSによる名前解決
クライアントの端末が、リクエストを送信したいコンピュータ(webサーバー)を特定するために、DNSサーバーに対して問い合わせを行い、DNSサーバーがドメイン名とIPアドレスの突き合わせを行います。
DNSサーバーからIPアドレスを取得する事ができたら、クライアントはリクエストの正しい送信先アドレスを把握する事ができます。
参考:
名前解決が行われた後は、クライアントとサーバーの間でコネクションを確立する必要があります。
HTTP(s)通信を行う事が決定しているため、クライアントは目的のサーバーの80(443)番ポートへのTCP接続を行います。
webサーバーのリクエスト受信、内部スクリプトの実行とレスポンスの返却。
webサーバーが、クライアントから送信されたリクエストを解釈し、指定された処理を実行します。
私は業務でRailsを使っているためRailsの例で言うと、リクエストを解釈し、ルーティングによって指定されたコントローラが、DBへの問い合わせや出力する文字列のエスケープ等を行うアクションを実行し、最終的に出力されたHTML(もしくはjson等)のレスポンスをクライアントへ返却します。
参考:
HTTPレスポンスには、以下のような情報が含まれます。
- ステータスライン
- HTTPのバージョン情報、ステータスコード、ステータスメッセージ
- レスポンスヘッダ
- リクエストヘッダと同じような情報
- レスポンスボディ
- POSTメソッド等で何らかの処理を要求する際に、パラメータを含める
クライアントがHTTPレスポンスを受け取り、レンダリングエンジンが解釈したドキュメントをブラウザ上に表示する
クライアントがHTTPレスポンスを受け取ると、最終的な画面描画を行うために、レンダリングエンジンがHTML、CSS、JavaScript等の解釈を行い、DOMを構築して画面描画を行います。
外部のリソース等も必要に応じてこのタイミングで取得(HTTPリクエスト)が行われ、最終的にクライアントの端末でフォーマットされたHTMLドキュメントを閲覧する事ができます。
レンダリングエンジンの動作に関する細かい話は、ググれば無限に情報が出てくるかと思うので、ここはお茶を濁してMDNの短いドキュメントを添付させていただきます。
補足
ちなみに、レンダリングエンジンがレスポンスを解釈してDOMを返すというのはブラウザの話で、ネイティブアプリ等がどのように描画を行なっているのかはちょっと分からないです。
また、キャッシュが使用されている場合も、上記とは処理の流れが異なります。
おしまい
ざっくりですが、リクエスト - レスポンスの間で、どのような処理が行われているのかを少し深掘りしてみました。
これだけたくさんの処理を、1秒にも満たない時間で行っているというのが脅威的ですね。
本当に凄い技術だなと思います。
各動作を細かく見るとまだまだ奥が深いですが、ひとまず一般的なwebアプリケーションの作成において最低限このくらいの理解度は必要なんではないかというところまでをまとめました。
補足などあればコメントお願いします。