PHP - WEB - 10. リダイレクト

引き続きHTTPレスポンスについて見ていきましょう。ここではリダイレクトという仕組みについて取り上げます。HTTPレスポンスのステータスコードには 300 番台のものが存在します。これらはリダイレクトと呼ばれるもので、異なるURLへの移動を意味します。もう少し詳細に言えば、リダイレクトは現在処理中のリクエストを完了するために、別のURLへのリクエストが必要であることをクライアント(Webブラウザ)に伝えます。

Webサーバがレスポンスに 302 番のようなリダイレクトを示すステータスコードを返却すると、レスポンスを受け取ったWebブラウザは location ヘッダを参照します。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:8080

続いてWebブラウザからログイン画面( login.html )にアクセスします。

https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/login.html

ログイン画面が表示されるので、デベロッパーツール(Networkタブ)を開いた状態でIDに Andy とパスワードに secret と入力して送信ボタンをクリックしてみましょう。

そうすると画面には menu.php に記述した内容が表示されるでしょう。またデベロッパーツールには上記のように2件の通信データが確認できるでしょう。2件の通信データのStatus欄にも 302200 とステータスコードを確認できます。ここでは1つ目の通信データ( login.php )をクリックしてレスポンスを確認してみましょう。

リダイレクト発生時のHTTPレスポンスのステータスコードが 302 となっている点を確認しておきましょう。

またリダイレクト発生時のHTTPレスポンスのヘッダフィールドをコピーしてテキストエディタに貼り付けると次のようになるでしょう。

content-type: text/html; charset=UTF-8
date: Thu, 25 Nov 2021 13:22:29 GMT
host: c6327f0f708344ba914531f340671547.vfs.cloud9.ap-northeast-1.amazonaws.com
location: menu.php
set-cookie: AWSALB=lnMgK4IrRprl+utkOz9uKe6IIxSYrTHCv/bRIWUnCZMnT7EXThrlnJW4rzNU6yYOgOLDFbpli1C8s3vzW7N6G/Rhs18JU7J7nqE8+R7F8/RideUycIPVwww3DmBS; Expires=Thu, 02 Dec 2021 13:22:29 GMT; Path=/
set-cookie: AWSALBCORS=lnMgK4IrRprl+utkOz9uKe6IIxSYrTHCv/bRIWUnCZMnT7EXThrlnJW4rzNU6yYOgOLDFbpli1C8s3vzW7N6G/Rhs18JU7J7nqE8+R7F8/RideUycIPVwww3DmBS; Expires=Thu, 02 Dec 2021 13:22:29 GMT; Path=/; SameSite=None; Secure
x-powered-by: PHP/7.2.24

ヘッダフィールドには location: menu.php が含まれているのがわかります。WebブラウザはHTTPレスポンスのステータスコードに 302 番を受け取ると location ヘッダを参照して menu.php に対してリクエストを再送します。リダイレクト時のリクエストによって menu.php の結果がレスポンスとして返却されるため、画面には menu.php の内容が表示されるのです。

リダイレクトによってアドレスバーのURLも menu.php に切り替わっている点も確認してください。このようにリダイレクトによってユーザに表示するページを切り替えることができます。

まとめ

  • ステータスコード 302 はリダイレクトを行う
  • リダイレクトは処理中のリクエストを完了するために、別のリクエストが必要であることをクライアントに伝える
  • リダイレクト時はレスポンスの location ヘッダに参照先のページを指定する