[311] [DFN[[CODE(HTTP)[[[302]]]]]] ([DFN[[[Found]]]]) は、[[リダイレクト]]を表す[[状態符号]]です。
[[リダイレクト]]の[[状態符号]]はいくつかありますが、 [CODE(HTTP)[[[302]]]]
が最も汎用的で、最も広く用いられています。

;; [312] 多くの[[プログラミング言語]]の[[ライブラリー]]や[[HTTP鯖]]などでは、
[[リダイレクト]]の[[状態符号]]を明示しない場合、 [CODE(HTTP)[[[302]]]]
が[[既定値]]として使われることが多いようです。

* 仕様書

[REFS[
- [309] '''[CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-6.4.3>'''
- [4] [CITE@en-US[Fetch Standard]] ([TIME[2015-07-07 18:54:30 +09:00]] 版) <https://fetch.spec.whatwg.org/#concept-http-fetch>
]REFS]

* 意味

[313] [CODE(HTTP)[[[302]]]] は、[[対象資源]]が一時的に異なる [[URL]]
にあることを示します。[[リダイレクト]]はまた変わるかもしれませんから、
[[クライアント]]は以後の[[要求]]でもまた同じ[[実効要求URL]]を使い続ける[RUBYB[べき]@en[ought to]]です。 [SRC[>>309]]

;; [314] 
ここでいう「一時的」とは「永続的」な[[リダイレクト]]を表す
[CODE[301]]
のような[[状態符号]]との対比です。
[CODE(HTTP)[[[301]]]] の時は[[クライアント]]は新しい [[URL]]
を以後かわりに使うべきとされています。

[6] [CODE[302]] は、[[HTTPリダイレクト]]の最も一般的な[[状態符号]]です。
「[[リダイレクト]]する」ということ以上の特別な意味は持っていないと解釈するのが一般的です。

[7] 他により適切な[[リダイレクト]]の意味を表す[[状態符号]]がない場合や、
特に注意して使い分ける必然性または意思がない場合に使われます。

[NOTE[
[3] 場合によっては [CODE(HTTP)[[[303]]]] を使うべきであるとの主張もたまに見かけますが、
主として[[宗教的]]な理由による主張に過ぎないようです。積極的に
[CODE(HTTP)[[[303]]]] に変更するべき理由は見当たりません。

;; [[HTTPリダイレクト]]の項も参照。

[5] [CODE[302]] はいつか[[リダイレクト]]を取りやめてかつてそこにあった[[コンテンツ]]を表示するように戻すことを暗示していると主張する人もいますが、
根拠はありません。
]NOTE]

[EG[
[9] 
[CODE[301]]
は恒久的な移転で、もう旧 [[URL]] は使うべきではない、
という意思を示したいときに使います。
そのような意図がなく、
元の [[URL]] を使い続けてほしいときや、
元の [[URL]] を使ってもいいが新しい [[URL]] を使ってもどちらでもいいようなとき、
あるいはどう扱われるべきか態度を決めかねるようなときには、
[CODE[302]]
を使うことができます。


]EG]

[EG[
[10] 
[[リダイレクト]]の[[状態符号]]を一々個別に指定する手段を提供しないような[[ソフトウェア]]の開発者は、
最も「汎用的」な[[リダイレクト]]である [CODE[302]] を使うのが妥当です。
]EG]

* 構文

[315] [[鯖]]は、別の [[URL]] を含む [CODE(HTTP)@en[[[Location:]]]]
[[ヘッダー]]を[[生成]]する[['''べき''']]です [SRC[>>309]]。

;; [12] なぜか[MUST[必須]]でなく[SHOULD[推奨]]に留まっていますが、
[CODE[302]] なのに [CODE[Location:]]
を指定しない[[応答]]を返すべき状況があるとは思えません。

[317] [[payload]] は通常は別の [[URL]] (群) への[[ハイパーリンク]]が含まれる短い[[ハイパーテキスト]]メモを含みます
[SRC[>>309]]。

;; [13] 「通常」となっていて要件とはされていないのですが、
一般的な慣習として、 [[HTML]] で[[リダイレクト]]先への[[リンク]]を書きます。
といっても[[リダイレクト]]に対応しない[[クライアント]]は (意図的なものを除けば)
基本的に存在しないですし、
この [[HTML]] が表示されることはまずあり得ないので、
あってもなくても構わないのですが。
(実際省略されることも、ないでもありません。)
[[リンク]]を1つ書くくらい[[サーバー]]ソフトウェア開発者にとって大した労力ではないですし、
転送量も誤差のようなものなので、よほどの理由がない限りは前例に倣っておくのでよさそうです。

;; [11] どちらも「別の」 [[URL]] と断られていますが、原理的には同じ [[URL]]
を指定することもできますし、「別の」 [[URL]] が更に[[リダイレクト]]で、
巡り巡って元の [[URL]] に戻ってくることもあり得ます。
[[リダイレクトループ]]と呼ばれる状態です。
こうした状態の処理は [[fetch]] や [[navigate]] で決まっています
(がそれに従わない[[クライアント]]もあるかもしれず、
障害を起こしかねないので、要注意です)。

* 文脈

[8] 
[[濫用]]例:
[[Deep Packet Inspection]],
[[captive portal]]

* 処理モデル

[316] [[利用者エージェント]]は、[CODE(HTTP)@en[[[Location:]]]]
[[ヘッダー]]の値を自動的な[[リダイレクト]]に使って[['''構いません''']] [SRC[>>309]]。

[318] 歴史的理由により、[[利用者エージェント]]は続きの[[要求]]で
[CODE(HTTP)@en[[[POST]]]] を [CODE(HTTP)[[[GET]]]] に変更して[['''構いません''']] [SRC[>>309]]。
[[Web互換性]]のためには、変更しなければ[['''なりません''']] [SRC[>>4]]。

;; [319] この動作が好ましくない時は [CODE(HTTP)[[[307]]]]
を使えます [SRC[>>309]]。

* 歴史

[REFS[
- [2] [[RFC 1945]] ([[HTTP/1.0]]) ([[IETF]] [[情報提供]] [[RFC]]) <urn:ietf:rfc:1945>
-- [CSECTION@en[10.3.3 302 Moved Temporarily]]
- [DEL[[[RFC 2068]] ([[HTTP/1.1]]) ([[IETF]] [[提案標準]])]] <urn:ietf:rfc:2068>
-- [CSECTION@en[10.3.3 302 Moved Temporarily]]
- [[RFC 2616]] ([[HTTP/1.1]]) ([[IETF]] [[原案標準]]) <urn:ietf:rfc:2616>
-- [CSECTION@en[10.3.3 302 Found]]
-- [1] [Errata] <http://purl.org/NET/http-errata#saferedirect>
]REFS]

[FIG(quote)[
[FIGCAPTION[
[310] RFC 1945 (HTTP/1.0); RFC 2068 (HTTP/1.1) 10.3.3 302 Moved Temporarily; RFC 2616 (HTTP/1.1) 10.3.3 302 Found
]FIGCAPTION]

> The requested resource resides temporarily under a different [DEL[[INS[{1945}]] URL]] [INS[[INS[{2068,2616}]] URI]].
Since the redirection [DEL[[INS[{1945,2068}]] may]] [INS[[INS[{2616}]] might]] be altered on occasion, the client [DEL[[INS[{1945}]] should]] [INS[[INS[{2068,2616}]] SHOULD]]
continue to use the Request-URI for future requests. [INS[[INS[{2068,2616}]] This response is only cach[INS[e]]able if indicated by a Cache-Control or Expires header field.]]

要求された資源は一時的に異なる URI の元にあります。
この redirect は折に触れて変わるかもしれないので、クライアントは[INS[[INS[(訳注)]]要求に使った]]
[CODE(ABNF)[[[Request-URI]]]] を将来の要求でも使い続ける'''べきです'''。
この応答は [CODE(HTTP)[[[Cache-Control]]]] 頭欄又は
[CODE(HTTP)[[[Expires]]]] 頭欄で示されている場合に限りキャッシュ可能です。

> [DEL[[INS[[INS[{2068}]] If the new URI is a location, its]] [DEL[[INS[{1945}]] The]] URL]] [INS[[INS[{2616}]] The temporary URI]] [DEL[[INS[{1945}]] must]] [INS[SHOULD]] be given by the Location field in the response.
Unless [DEL[[INS[{1945}]] it was a HEAD request]] [INS[the request method was HEAD]], the [DEL[[INS[{1945}]] Entity-Body]] [INS[entity]]
of the response [DEL[[INS[{1945}]] should]] [INS[SHOULD]] contain a short [INS[hypertext]]
note with a hyperlink to the new URI(s).

一時 URI は応答の [CODE(HTTP)[[[Location]]]] 欄に与える'''べきです'''。
要求 method が [CODE(HTTP)[HEAD]] でない限り、
応答の実体は新しい URI (群) へのハイパーリンクが入った短いハイパーテキストの覚書を含む'''べきです'''。

> If the 302 status code is received in response to a request [DEL[[DEL[[INS[{1945}]] using the POST method]] [INS[[INS[{2068,2616}]] other than GET or HEAD]]]] [INS[[INS[{errata}]] method that is known to be "safe", as defined in section 9.1.1, then the request MAY be automatically redirected by the user agent without confirmation.  Otherwise]], the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.

「安全」と分かっている method の要求に対する応答で
[CODE(HTTP)[302]] 状態符号を受取った時は、
利用者エージェントは要求を確認なしに自動的に redirect
しても'''構いません'''。それ以外の場合は、
利用者エージェントは利用者の確認を得ることなしに自動的に
redirect しては'''なりません'''。そうしないと要求が発行された条件が変わってしまうかもしれません。

[DEL[

> [INS[{1945,2068}]] Note: When automatically redirecting a POST request after receiving
a 302 status code, some existing [INS[HTTP/1.0]]
user agents will erroneously change it into a GET request.

注意 : [CODE(HTTP)[301]] 状態符号を受信して [CODE(HTTP)[[[POST]]]]
要求を自動的に redirect するときに、誤って [CODE(HTTP)[GET]]
要求に変えてしまう HTTP/1.0 利用者エージェントが存在します。
]DEL]

[INS[

> [INS[{2616}]] 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.

注意 : RFC 1945 及び RFC 2068 は、クライアントが redirect
要求で method を変更することを許さないと規定しています。
しかし、ほとんどの既存の利用者エージェントは [CODE(HTTP)[302]]
を [CODE(HTTP)[[[303]]]] 応答のように扱い、元の要求 method
に関わらず [CODE(HTTP)[Location]] 欄値を [CODE(HTTP)[GET]]
します。どの種の再動作をクライアントに期待するかを曖昧なく明らかにしたいサーバーのために、
状態符号 [CODE(HTTP)[303]] 及び [CODE(HTTP)[[[307]]]] が追加されました。
]INS]
]FIG]

[308] [CITE@en[HTTP - WHATWG Wiki]]
( ([TIME[2013-12-19 01:12:07 +09:00]] 版))
<http://wiki.whatwg.org/wiki/HTTP#Redirects>