(十) HTTPプロトコル
10.1 プロトコルとは?
- プロトコルは、特定の個人または組織が事前に定めた一連の規則であり、すべての参加者がこの規則に従うことで、意思疎通が円滑に行える。
- プロトコルとは、標準的な仕様であり、他の個人や団体によって策定される。
- あなたが話すことが理解でき、あなたが話すことも理解できる。これは、共通の規範、つまり「中国語普通话プロトコル」が存在することを意味する。このプロトコルに従うことにより、コミュニケーションがスムーズになる。
10.2 HTTPプロトコルとは?
- HTTPプロトコルは、W3Cによって策定されたハイパーテキスト転送プロトコルである。(通信プロトコル:メッセージ送信のテンプレートが事前に定義されている。)
W3C:
- ワールド・ワイド・ウェブ・コンソーシアム
- 標準の策定機関:HTTP、HTML4.0、HTML5、XML、DOMなどの規格はすべてW3Cによって策定されている。
- ワールド・ワイド・ウェブの創設者:ティム・バーナース=リー
ハイパーテキスト:
- ハイパーテキストとは、通常のテキストではなく、音声、動画、画像などのマルチメディアを含む。
- HTTPプロトコルは、通常の文字列だけでなく、音声、動画、画像などのストリームデータも送信可能。
このプロトコルはブラウザとサーバーの間を移動する。ブラウザがサーバーにデータを送る際にはHTTPプロトコルに従い、逆も同様。これにより、ブラウザとサーバーは相互に依存しないように設計される。
解耦合とは?
- ブラウザはサーバーに依存しない。
- サーバーもブラウザに依存しない。
B/S構造とは?
- ブラウザがWEBサーバーにアクセスするシステム構造
- ブラウザがWEBサーバーにデータを送る行為は「リクエスト」と呼ばれる。
- WEBサーバーがブラウザにデータを送る行為は「レスポンス」と呼ばれる。
HTTPプロトコルはリクエストプロトコルとレスポンスプロトコルで構成される。
リクエストプロトコル:
- ブラウザがWEBサーバーにデータを送る際、そのデータは一定の形式に従う必要がある。この形式は、送信データのフォーマットを規定している。
レスポンスプロトコル:
- WEBサーバーがブラウザにデータを送る際、そのデータも一定の形式に従う必要がある。この形式は、送信データのフォーマットを規定している。
HTTPプロトコルは事前に定義されたメッセージテンプレートである。
- どのブランドのブラウザであっても同じようにリクエストを送信する。
- どのブランドのWEBサーバーでも同じようにリクエストを受け取る。
- FirefoxブラウザはTomcatサーバーにもJettyサーバーにもリクエストを送信できる。ブラウザはサーバーのブランドに依存しない。
- WEBサーバーもブラウザのブランドに依存しない。Firefox、Chrome、IEなど、どのブラウザでも対応可能。
10.3 HTTPリクエストプロトコルとは?
HTTPリクエストプロトコルは以下の4つの要素から構成される:
- リクエスト行
- リクエストヘッダー
- 空行
- リクエストボディ
GETリクエストの例:
GET /s5/GetServlet?username=jack&userpwd=123 HTTP/1.1
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.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Cookie: JSESSIONID=C474E84D95FD363289A6EDC5042DDDD3
Host: localhost:8080
Referer: http://localhost:8080/s5/
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
解析:
GET /s5/GetServlet?username=jack&userpwd=123 HTTP/1.1- リクエスト行。GETメソッドを使用して/s5/GetServletリソースをリクエストし、パラメータとしてusernameとuserpwdを渡す。Accept:- クライアントが受け入れ可能なレスポンスのコンテンツタイプとその優先度を示す。Accept-Encoding:- クライアントが受け入れ可能なレスポンスの圧縮形式。Accept-Language:- クライアントが受け入れ可能なレスポンスの言語。Connection:- クライアントがサーバーとの長時間接続を維持することを希望する。Cookie:- リクエストに含まれるクッキー情報。Host:- リクエストのターゲットホストとポート番号。Referer:- リクエスト元ページのURL。Sec-Fetch-*:- Fetch APIをサポートするためのセキュリティヘッダー。Upgrade-Insecure-Requests:- HTTPリクエストをHTTPSにアップグレードするよう要求。User-Agent:- クライアントのブラウザとオペレーティングシステム情報を示す。sec-ch-ua*:- ユーザーエージェントの詳細情報。
POSTリクエストの例:
POST /s5/PostServlet HTTP/1.1
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.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 24
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=C474E84D95FD363289A6EDC5042DDDD3; b-user-id=e4b47408-2e2c-6053-eb41-b9eb4a54dff1
Host: localhost:8080
Origin: http://localhost:8080
Referer: http://localhost:8080/s5/
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
username=123&userpwd=123
- リクエスト行は以下の3要素で構成される:
- リクエストメソッド(7種類)
- URI
- HTTPプロトコルバージョン
- リクエストメソッド(7種類)
- GET(一般的に使用される)
- POST(一般的に使用される)
- DELETE
- PUT
- HEAD
- OPTIONS
- TRACE
- URI(Uniform Resource Identifier):リソースを識別するための一意な文字列。しかし、リソースの場所を特定することはできない。
- URL(Uniform Resource Locator):リソースの場所を示す。URIの一種であり、リソースを特定できる。
- HTTPプロトコルバージョン
- リクエストヘッダー:
- ホスト
- ポート
- ブラウザ情報
- プラットフォーム情報
- Cookie
- その他
- 空行:リクエストヘッダーとリクエストボディを区切る。
- リクエストボディ:サーバーに送信する実際のデータ。
10.4 HTTPレスポンスプロトコルとは?
HTTPレスポンスプロトコルは以下の4つの要素から構成される:
- ステータス行
- レスポンスヘッダー
- 空行
- レスポンスボディ
GETリクエストのレスポンス例:
// ステータス行
HTTP/1.1 200 ok
// レスポンスヘッダー
Content-Type: text/html;charset=UTF-8
Content-Length: 165
Date: Sat, 08 Jul 2023 09:55:31 GMT
Keep-Alive: timeout=20
Connection: keep-alive
// 空行
// レスポンスボディ
<html lang="en">
<head>
<meta charset="UTF-8">
<title>from get servlet</title>
</head>
<body>
<h1>from get servlet</h1>
</body>
</html>
POSTリクエストのレスポンス例:
// ステータス行
HTTP/1.1 200
// レスポンスヘッダー
Content-Type: text/html;charset=UTF-8
Content-Length: 167
Date: Sat, 08 Jul 2023 10:16:54 GMT
Keep-Alive: timeout=20
Connection: keep-alive
// 空行
// レスポンスボディ
<html lang="en">
<head>
<meta charset="UTF-8">
<title>from post servlet</title>
</head>
<body>
<h1>from post servlet</h1>
</body>
</html>
- ステータス行は以下の3要素で構成される:
- プロトコルバージョン
- ステータスコード
- ステータスメッセージ
- ステータスコード:
- 200:リクエスト成功
- 404:リソースが見つからない
- 405:リクエストメソッドが不正
- 500:サーバーエラー
- ステータスメッセージ:正常終了、リソースが見つからないなど。
- レスポンスヘッダー:
- コンテンツタイプ
- コンテンツ長
- 日時
- その他
- 空行:レスポンスヘッダーとレスポンスボディを区切る。
- レスポンスボディ:レンダリングされ、ブラウザ上で表示される内容。
10.5 GETとPOSTの違い
- GETリクエストはURIにデータを追加し、アドレスバーに表示される。リクエスト行でデータを送信。
- POSTリクエストはリクエストボディにデータを含め、アドレスバーには表示されない。リクエストボディでデータを送信。
- GETリクエストは文字列のみ送信可能。データ長には制限あり。POSTは任意のデータを送信可能。
- GETリクエストは大量データを送信不可。POSTは理論的には無制限。
- GETはサーバーからデータを取得するのに適している。POSTはサーバーにデータを送信するのに適している。
- GETは安全。POSTは危険。POSTはサーバーにデータを送信するため、セキュリティリスクがある。
- GETリクエストはキャッシュ可能。POSTはキャッシュ不可。
GETリクエストのキャッシュ回避方法:
- リクエストパスを毎回変更することでキャッシュを回避。
- 時間スタンプを追加する。
POSTリクエストはキャッシュ不可。
GETとPOSTの使い分け:
- データ取得:GET
- データ送信:POST
- フォーム送信は通常POST
- パスワードなどの機密情報はPOST
- ファイルアップロードはPOST
GETとPOSTのデータ形式は同じだが、位置が異なる。
- name=value&name=value&name=value&name=value
GETとPOSTのデータ形式は同じであるが、位置が異なる。
補足:キャッシュ機構
- 文字列定数プール:文字列の再利用
- 整数定数プール:-128〜127の整数は再利用
- コネクションプール:データベース接続の再利用
- スレッドプール:Tomcatでの並列処理
- Redis:NoSQLデータベース、キャッシュ
- ServletContext:アプリケーションレベルのキャッシュ