PHP - WEB - 6. HTTPリクエストの詳細(POSTリクエスト)
引き続きHTTPリクエストについて学習していきましょう。
繰り返しになりますが HTTPリクエストは以下の3つのパートで構成されています。
- リクエストライン
- ヘッダフィールド
- ボディパート
先ほど学習したGETリクエストの場合は、リクエストラインとヘッダフィールドは利用しているものの、ボディパートの利用はありませんでした。
次はPOSTリクエストについて詳しく検証していきましょう。
HTTPリクエストのキャプチャー(POSTリクエスト)
続いてログインプログラム( login.html
)について POST
リクエストを送信するように修正してみましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHP Sample</title>
</head>
<body>
<h3>Login</h3>
<hr>
<form action="login.php" method="post">
<input type="text" name="id">
<input type="password" name="password">
<input type="submit" value="login">
</form>
</body>
</html>
form
タグのmethod
属性をpost
に修正します。
同様にPOSTリクエストを処理するプログラム( login.php
)も $_GET
変数から $_POST
変数に修正します。
<?php
$id = $_POST["id"];
$password = $_POST["password"];
$message = "NG";
if ($id === "Andy" && $password === "secret") {
$message = "OK";
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHP Sample</title>
</head>
<body>
<h1>Login <?php echo $message; ?></h1>
</body>
</html>
それでは実際にPOSTリクエストのキャプチャーを取得してみましょう。まずは以下のURLを入力してログイン画面( login.html
)にアクセスします。
https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/login.html
次にデベロッパーツールを開いて Network タブを選択します。デベロッパーツール(Networkタブ)を開いた状態で、IDとパスワードを入力して送信ボタンをクリックしてみましょう。GETリクエスト時と同様にデベロッパーツール上に通信データが1件表示されるでしょう。
次のこの通信データをクリックすると次のように表示されるでしょう。画面をスクロールすると「Request Headers」というセクションがあります。
ここに表示されている内容がHTTPリクエスト(厳密には擬似ヘッダフィールド(リクエストライン)とヘッダフィールド)です。デベロッパーツールに表示されている内容をコピーしてテキストエディタに貼り付けると次のようになります。
:authority: c6327f0f708344ba914531f340671547.vfs.cloud9.ap-northeast-1.amazonaws.com
:method: POST
:path: /login.php
:scheme: https
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
accept-encoding: gzip, deflate, br
accept-language: ja,en-US;q=0.9,en;q=0.8
cache-control: max-age=0
content-length: 23
content-type: application/x-www-form-urlencoded
cookie: __Host-previewc9corsvfs_9c0d5j7Z1PFSFxRo=9ck6M6IHHfbozVDiAEl36pzUcbrA5FKq; AWSALB=PrEQhlGUx2qXjtx6MhYPSLs69ju34skNpD4swd2nM8vKSMYO35cBxm3XagFkKenmo9naMApd6uzKg9AEiA8J+iiN5q2h/DndkSYeJIjEDaQJYHu3G6ojiWhXQk1r; AWSALBCORS=PrEQhlGUx2qXjtx6MhYPSLs69ju34skNpD4swd2nM8vKSMYO35cBxm3XagFkKenmo9naMApd6uzKg9AEiA8J+iiN5q2h/DndkSYeJIjEDaQJYHu3G6ojiWhXQk1r
origin: https://c6327f0f708344ba914531f340671547.vfs.cloud9.ap-northeast-1.amazonaws.com
referer: https://c6327f0f708344ba914531f340671547.vfs.cloud9.ap-northeast-1.amazonaws.com/login.html
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
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 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36
これらはHTTPリクエストの1つ目のパートであるリクエストラインと2つ目のパートであるヘッダフィールドの情報です。ここまでの内容は GET
リクエストの場合とよく似ています。ここでは :method
と :path
に注目してください。
:method: POST
:path: /login.php
:method
擬似ヘッダフィールドの値が POST
となっていることがわかるでしょう。また :path
擬似ヘッダフィールドには GETリクエストのように画面から入力されたデータ( ?id=Andy&password=secret
)が付与されていない点に気づくでしょう。
それでは画面から入力されたデータはどのように送信されるのでしょうか。実はPOSTリクエストの場合は、画面から入力されたデータを :path
の一部として送信するのではなく、HTTPリクエストのボディパートと呼ばれる領域に含んで送信するようになっています。
HTTPでは送信データを大別すると「ヘッダフィールド(リクエストライン含む)」と「ボディパート」の2つの領域が用意されています。GETリクエストではボディパートは利用しませんでしたが、POSTリクエストではボディパートを利用するという仕組みになっています。
デベロッパーツール上で Payload
タブを選択すると「Form Data」というセクションがあります。ここに表示されている内容がHTTPリクエストのボディパートに含まれる送信データです。
ここには画面から入力したパラメータが次のように表示されているのがわかります。
id: Andy
password: secret
このようにPOSTリクエストの場合は、ヘッダフィールド(擬似ヘッダフィールド含む)だけを送信するのではなく、それに加えてボディパートに画面から入力されたデータを格納して送信します。
GETリクエストとPOSTリクエストの違い
GETリクエストとPOSTリクエストの違いを整理すると次のようになります。
GETリクエスト | POSTリクエスト | |
---|---|---|
リクエストライン (擬似ヘッダフィールド) |
:method: GET :path に入力データを付加する |
:method: POST |
ヘッダフィールド | 自動的に様々なヘッダが付加される | 自動的に様々なヘッダが付加される |
ボディパート | 利用しない | 入力データを含む |
GETリクエストは :path
に入力データを付加するため、ブラウザ上ではアドレスバーにリクエストパラメータが見えるようになります。
このような挙動はログイン機能には不向きですが、検索機能で有効に機能します。GETリクエストの特徴である「URLに入力パラメータが付与される」という点はURLを再利用できるというメリットがあります。具体的にはURLをお気に入りに登録しておくなどしてパラメータ付きのURLを再利用できます。
一方でPOSTリクエストの場合は、画面からの入力データはボディパートに格納されるので、ユーザの目に触れにくくなります。
ログイン機能のようなケースではPOSTリクエストを使うことが自然でしょう。
POSTリクエストを使えば安全に送信できる、というわけではない点に注意してください。デベロッパーツールのようなネットワークの通信データをキャプチャーするソフトウェアを使えば、簡単に入力データを盗み見ることができます。暗号化のような安全な通信を確保するには
https
のような仕組みを利用する必要があります。
他にもユーザ作成処理であったり、ショッピングカートの購入処理であったり、サーバ上に何かデータを作成(更新、削除)する場合はPOSTリクエストを送信することが一般的です。
まとめ
- GETリクエストとPOSTリクエストでデータの送信方法が異なる
- GETリクエストはリクエストパラメータをリクエストライン(擬似ヘッダフィールド)に含む
- POSTリクエストはリクエストパラメータをボディパートに含む