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="text" 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欄にも 302200 とステータスコードを確認できます。ここでは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 ヘッダに参照先のページを指定する