Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

ステータス303と307

303(See Other)も307(Temporary Redirect)もあんまり見聞きしないステータスですが、気になっていたので定義と実際の挙動を見てみました。
それぞれの定義は、次のURLを参照。

また、コードは次のものを用意しました。

  • redirect.html
<html>
<body>
<form action="redirect.php" method="post">
<input type="hidden" name="val" value="hogehoge">
<input type="submit">
</form>
</body>
</html>
<?php
header('Location: http://www.example.com/redirect02.php', true, 307);
//header('Location: http://www.example.com/redirect02.php', true, 303);
?>
<a href="http://www.example.com/redirect02.php">こちら</a>
  • redirect02.php
<?php
var_dump($_GET);
var_dump($_POST);

挙動確認に使用したブラウザは、

  • Firefox 2.0.0.2
  • Internet Explorer6、7

です。
結果ですが、ステータス303の場合、


The response to the request can be found under a different URI and
SHOULD be retrieved using a GET method on that resource.

の通り、redirect02.phpにGETでアクセスします。これはステータス302(Found)の場合と同じ動きです。
一方、ステータス307の場合、redirect02.phpにPOSTされます。redirect.htmlのフォームで、actionをgetに変更するとGETでアクセスされます。「最初のリクエスト内容と同じリクエストをredirect先に行う」といったものになるようです。なるほどねぇ。
で、307の場合、Firefoxでは

のようなダイアログが表示されますが、Internet Explorerでは何事もなくredirectされました。設定如何かも知れませんが、使う場合は気にしておいた方が良いかも知れません。
しかし、


Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request. However, most
existing user agent implementations treat 302 as if it were a 303
response, performing a GET on the Location field-value regardless
of the original request method. The status codes 303 and 307 have
been added for servers that wish to make unambiguously clear which
kind of reaction is expected of the client.

という経緯(クライアントが言うこと聞いてくれないから)で作られたステータスコード、というのも面白い。