[1] 
[[HTTP]]
の[[状態符号]]
[DFN[[CODE(HTTP)@en[[[303]]]]]] は、
他の [[URL]] を [CODE(HTTP)@en[[[GET]]]]
するべきことを示す[[リダイレクト]]です。

* 仕様書

[REFS[
- [308] '''[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.4>'''
- [306] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.3.3>
- [10] [CITE@en-US[Fetch Standard]] ([TIME[2015-07-07 18:54:30 +09:00]] 版) <https://fetch.spec.whatwg.org/#concept-http-fetch>
]REFS]

* 意味

[309] [CODE(HTTP)[[[303]]]] は、[[鯖]]が[[利用者エージェント]]に対して [[URL]]
を示して異なる[[資源]]に[[リダイレクト]]し、元の[[要求]]に対する間接的な[[応答]]を提供することを意図するものです [SRC[>>308]]。

;; [310] ただし[[リダイレクト]]先の [[URL]] が元の[[実効要求URL]]
と等価とみなせるわけではありません [SRC[>>308]]。

[313] [CODE(HTTP)[[[303]]]] はどの[[要求メソッド]]にも適用可能です。
主として[CODE(HTTP)[[[POST]]]] の出力によって[[利用者エージェント]]を選択された[[資源]]に[[リダイレクト]]して、
[CODE(HTTP)[[[POST]]]] [[応答]]に対応する情報を元の[[要求]]とは独立に単独で識別したり、
[[ブックマーク]]したり、[[キャッシュ]]したりできるようにするのが主たる用途です。
[SRC[>>308]]

[314] [CODE(HTTP)@en[[[GET]]]] [[要求]]に対する [CODE(HTTP)[[[303]]]]
[[応答]]は、[[起源鯖]]が[[対象資源]]について [[HTTP]] により[RUBYB[[[転送]]]@en[transfer]]できる[[表現]]を持っていないことを示します。
[CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]の値は[[対象資源]]の説明を含む[[資源]]を指しており、
その[[資源]]を[RUBYB[取得]@en[retrieve]]すると、
[[受信者]]にとって有用な[[表現]]を得られるかもしれません
(ただし元の[[対象資源]]を表現することを意味しません)。
[SRC[>>308]]

[9] ○○の場面では [CODE(HTTP)[[[302]]]] よりも [CODE(HTTP)[[[303]]]]
が適切である、といった類の主張もたまにみられますが、[[宗教的]]なもので、
その方が特別に好ましい場面があるとは言いがたいと思われます。

[13] 実際の所いつ (他の[[状態符号]]ではなく) [CODE(HTTP)[303]]
を使うべきなのかは不明です。

;; [[HTTPリダイレクト]]の項も参照。

* 文脈

[305] [[起源鯖]]は、 [CODE(HTTP)@en[[[POST]]]] の処理の結果が既存の[[資源]]の[[表現]]と等価である時には、 その 
[[URL]] を [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]に指定した 
[CODE(HTTP)[[[303]]]] [[応答]]を送信することができます [SRC[>>306]]。

* 構文

[312] [[鯖]]は[[リダイレクト]]先の[[資源]]の [[URL]]
を [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]に指定します [SRC[>>308]]。

;; [316] なぜか[[事実の文]]でしかなく、 [['''MUST''']] にはなっていません。
([[IETF]] では一般的な品質です。)

[315] [CODE(HTTP)@en[[[HEAD]]]] [[要求]]の場合を除き、
[CODE(HTTP)[[[303]]]] [[応答]]の[[表現]]は [CODE(HTTP)@en[[[Location:]]]]
[[ヘッダー]]の [[URL]] と同じ [[URL]] への[[ハイパーリンク]]を含む短い[[ハイパーテキスト]]のメモを含める[RUBYB[べき]@en[ought to]]です。
[SRC[>>308]]

* 処理モデル

[311] [[利用者エージェント]]は、 [CODE(HTTP)@en[[[Location:]]]]
[[ヘッダー]]の [[URL]] を対象とした[RUBYB[取得]@en[retrieval]]の[[要求]]を
(その [[URL]] も [[HTTP]] なら [CODE(HTTP)@en[[[GET]]]] や
[CODE(HTTP)@en[[[POST]]]] の[[要求]]で) 実行し、その結果を元の[[要求]]の結果として提示できます。
ただしその[[要求]]の結果も[[リダイレクト]]かもしれません。 [SRC[>>308]]

;; つまり、[[利用者エージェント]]は [CODE(HTTP)[[[303]]]] 
[[応答]]でも自動的に[[リダイレクト]]を処理して構いません。

[11] [[要求メソッド]]は [CODE(HTTP)@en[[[GET]]]] に変更しなければ[['''なりません''']]
[SRC[>>10]]。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[307] RFC 2068・2616 (HTTP/1.1) 10.3.4 303 See Other
]FIGCAPTION]

> The response to the request can be found under a different URI and
SHOULD be retrieved using a GET method on that resource. This method
exists primarily to allow the output of a POST-activated script to
redirect the user agent to a selected resource. The new URI is not a
substitute reference for the originally requested resource. The 303
response [DEL[is not cachable]] [INS[MUST NOT be cached]],
but the response to the second (redirected) request [DEL[MAY]] [INS[might]] be cacheable.

要求に対する応答は異なる URI に見つかり、その資源を [CODE(HTTP)[[[GET]]]]
method を使って取り出す'''べきです'''。この方法は、主として
[CODE(HTTP)[[[POST]]]] で活性化されたスクリプトの出力が利用者エージェントを選択された資源に[RUBY[再指向] [リダイレクト]]するために存在します。
新しい URI は元の要求資源の代替参照ではありません。
[CODE(HTTP)[303]] 応答はキャッシュ'''してはなりません'''が、
第2 (再指向先) 要求の応答はキャッシュ可能かもしれません。

> [DEL[If the new URI is a location, its URL]] [INS[The different URI]]
SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the
response SHOULD contain a short hypertext note with a hyperlink to
the new URI(s).

異なる URI は応答の [CODE(HTTP)[Location]] 欄で与える'''べきです'''。
要求 method が [CODE(HTTP)[[[HEAD]]]] でない限り、
応答の実体は新しい URI (群) へのハイパーリンクの入った短いハイパーテキスト覚書を含む'''べきです'''。

[INS[
> Note: Many pre-HTTP/1.1 user agents do not understand the 303
status. When interoperability with such clients is a concern, the
302 status code may be used instead, since most user agents react
to a 302 response as described here for 303.

注意 : 多くの HTTP/1.1 以前の利用者エージェントは [CODE(HTTP)[303]]
状態を理解しません。そのようなクライアントとの相互運用性を気にするのであれば、
代わりに [CODE(HTTP)[[[302]]]] 状態符号を使っても構いません。
ほとんどの利用者エージェントはここで [CODE(HTTP)[303]]
について説明したように [CODE(HTTP)[302]] 応答に対しても再動作します。
]INS]
]FIG]

** 初期の実装

[2] [[NC]] 4.01 は未対応。

[3] [[WinIE]] は1で既に対応しています。とはいってもきっと [CODE(HTTP)[303]] は知らなくて、 [CODE(HTTP)[3]] で [CODE(HTTP)[[[Location:]]]] 欄があったからそれに飛んだだけだとは思います。
- [4] [[MosaicView]] 2.0 は対応しています。事情は >>3 同様でしょう。
- [5] [[Infomosaic]] も >>3-4 に同じ。
- [6] 一方 [[MosaicNetscape]] 0.9 は未対応。 Netscape の最初の code で書き直したのかな?

[7] [[Mozilla]] ([[Gecko]]) はもちろん対応しているのですが、最近の版ではリダイレクト先に [CODE(HTTP)[POST]] 内容を再送してしまう不具合があります。 (1.3 以前は大丈夫で、 1.4b 以降は駄目です。その途中のどこで enbug したのかは調べてません。 1.5 ではまだ直ってません。)

[8] >>7 うーんと、 2616 には [CODE(HTTP)[GET]] する'''べき'''とは書かれているけど、 [CODE(HTTP)[POST]] しては'''ならない'''わけではないから・・・とはいえ、 [CODE(HTTP)[POST]] 後の処理のために用意されたとはっきり書かれているし、 >>7 の挙動は不具合というより他ない。 2616 で追加された [CODE(HTTP)[[[302]]]] の補足説明からも UA が取るべき行動でないことは明らか。

** 

[304] [CITE@en[URLs in Data Primer]]
( ([TIME[2013-05-30 21:44:23 +09:00]] 版))
<http://www.w3.org/TR/2013/WD-urls-in-data-20130604/#http-responses>


[317] [CITE[Status codes in HTTP]]
( ([TIME[1999-10-27 03:40:19 +09:00]] 版))
<http://www.w3.org/Protocols/HTTP/HTRESP.html#z10>

[12] [CITE@en[Allow user agents to transmit RST_STREAM upon seeing a redirect · whatwg/fetch@af0dc92]]
([TIME[2016-03-26 11:55:53 +09:00]] 版)
<https://github.com/whatwg/fetch/commit/af0dc923f7636751996a9762309904511725a1a7>

[FIG(quote)[
[FIGCAPTION[
[14] [CITE[Cool URIs for the Semantic Web]]
([TIME[2008-12-03 00:30:18 +09:00]])
<https://www.w3.org/TR/cooluris/#r303gendocument>
]FIGCAPTION]

> The second solution is to use a special HTTP status code, 303 See Other, to give an indication that the requested resource is not a regular Web document.

]FIG]


[15] [CITE@en[Stream-based requests (Request with ReadableStream)]]
([[yutakahirano]]著, [TIME[2017-01-17 16:31:32 +09:00]])
<https://github.com/whatwg/fetch/commit/0c470b5860fe690b1136b0242951f682405103cc>

[16] [CITE@en[More eargerly send RST_STREAM on redirects]]
([[annevk]]著, [TIME[2017-11-24 20:11:46 +09:00]])
<https://github.com/whatwg/fetch/commit/fd286755e9664d570260c16f7c1933f424d2f39a>

[17] [CITE@en[Preserve HEAD method on 303 redirect]]
([[annevk]]著, [TIME[2018-08-17 23:27:58 +09:00]])
<https://github.com/whatwg/fetch/commit/6f29b764cc57aaf2f431e15a3f0fec029926e9e0>

[18] [CITE@en[303 redirects should preserve HEAD · Issue #753 · whatwg/fetch]]
([TIME[2018-08-23 18:51:23 +09:00]])
<https://github.com/whatwg/fetch/issues/753>

[19] [CITE@en[Preserve HEAD method on 303 redirect by annevk · Pull Request #796 · whatwg/fetch]]
([TIME[2018-08-23 18:52:35 +09:00]])
<https://github.com/whatwg/fetch/pull/796>