PHP - WEB - 9. リダイレクト
引き続きHTTPレスポンスについて見ていきましょう。ここではリダイレクトという仕組みについて取り上げます。HTTPレスポンスのステータスコードには 300
番台のものが存在します。これらはリダイレクトと呼ばれるもので、異なるURLへの移動を意味します。もう少し詳細に言えば、リダイレクトは現在処理中のリクエストを完了するために、別のURLへのリクエストが必要であることをクライアント(Webブラウザ)に伝えます。
Webサーバがレスポンスに 302
番のようなリダイレクトを示すステータスコードを返却すると、レスポンスを受け取ったWebブラウザは Location
ヘッダに指定されたURLに対して即座にリクエストを送信します。
PHPプログラムの開発(ログイン処理のリダイレクト)
ここでは以前に作成したログインプログラムを修正してリダイレクトの挙動について学習します。まずはログイン画面( login.html
)です。
<!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
にしている点だけ注意してください。もしGETリクエストで送信してしまうと入力したIDやパスワードがクエリパラメータとしてURLに付与されてしまうためです。
次にリクエストを処理するプログラム( login.php
)です。以下のように修正します。
<?php
$id = $_POST["id"];
$password = $_POST["password"];
if ($id === "Andy" && $password === "secret") {
header("Location: menu.php");
} else {
header("Location: login.html");
}
ここではPOSTリクエストから受け取ったIDが Andy
、パスワードが secret
だった場合に header("Location: menu.php");
を呼び出しています。 header
関数は以前に Content-type
ヘッダを指定する際にも利用しましたが、レスポンスのヘッダフィールドを指定するための関数です。ここでは引数に "Location: menu.php"
と指定してるので、リダイレクト時の遷移先のURLは menu.php
なります。また header
関数で Location
ヘッダを指定するとレスポンスのステータスコードも 302
番に置き換わります。
またログインに失敗した場合も同様に header("Location: login.html");
としています。これによってリダイレクト先のURLは login.html
となります。
さいごにログイン成功時のリダイレクト先となるファイル( menu.php
)も作成しておきましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHP Sample</title>
</head>
<body>
<h3>Menu</h3>
<hr>
<ul>
<li>ToDo</li>
</ul>
</body>
</html>
ここではファイル名は menu.php
としていますが現時点では画面を表示するためのHTMLコードだけを記述しています。以上でプログラムの作成は完了です。
次にビルトインWebサーバを起動しましょう。
$ php -S localhost:8000
続いてWebブラウザからログイン画面( login.html
)にアクセスします。
http://localhost:8000/login.html
ログイン画面が表示されるので、デベロッパーツール(Networkタブ)を開いた状態でIDにAndyとパスワードにsecretと入力して送信ボタンをクリックしてみましょう。
そうすると画面には menu.php
に記述した内容が表示されるでしょう。またデベロッパーツールには上記のように2件の通信データが確認できるでしょう。2件の通信データのStatus欄にも 302
、 200
とステータスコードを確認できます。ここでは1つ目の通信データ( login.php
)をクリックしてレスポンスを確認してみましょう。
リダイレクト発生時のHTTPレスポンスをコピーしてテキストエディタに貼り付けると次のようになるでしょう。
HTTP/1.1 302 Found
Host: localhost:8000
Date: Mon, 17 Aug 2020 12:33:00 GMT
Connection: close
X-Powered-By: PHP/7.3.11
Location: menu.php
Content-type: text/html; charset=UTF-8
レスポンスのステータスライン(1行目)を見るとステータスラインが 302
となっているのがわかります。またヘッダフィールドには Location: menu.php
が含まれているので、Webブラウザは menu.php
に対してリクエストを再送します。リダイレクト時の2つ目のリクエストによって menu.php
の結果がレスポンスとして返却されるため、画面には menu.php
の内容が表示されるのです。
まとめ
- ステータスコード
302
はリダイレクトを行う - リダイレクトは処理中のリクエストを完了するために、別のリクエストが必要であることをクライアントに伝える
- リダイレクト時はレスポンスの
Location
ヘッダに参照先のページを指定する