[1] [DFN[[CODE(HTTP)@en[[[Location:]]]]]] [[ヘッダー]]は、[[リダイレクト]]先の
[[URL]] を指定するものです。

[450] [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]は通常 [CODE(HTTP)[[[3xx]]]]
[[状態符号]]と共に利用します。[[利用者エージェント]]は[[リダイレクト]]の[[応答]]を受け取ると、
自動的に [CODE(HTTP)[[[Location:]]]] で指定された [[URL]]
に改めて[[要求]]を送信します。

[FIG(sequence)[
:C:[[利用者エージェント]]
:S:[[起源鯖]]
:S2:[[起源鯖]]'
:C -> S:[[要求]]
:S -> C:[CODE(HTTP)[[[3xx]]]] [CODE(HTTP)@en[[[Location:]] [VAR[URL]]]]
:C -> S2:新 [VAR[URL]] に[[要求]]
:S2 -> C:[[応答]]
]FIG]

* 仕様書

[REFS[
- [424] '''[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-7.1.2>'''
- [421] [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>
- [412] [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>
- [448] [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.1>
- [441] [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.2>
- [443] [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>
- [445] [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>
- [447] [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.7>
- [2] [CITE@en[RFC 7238 - The Hypertext Transfer Protocol Status Code 308 (Permanent Redirect)]] ([TIME[2014-06-07 01:57:48 +09:00]] 版) <https://tools.ietf.org/html/rfc7238#section-3>
- [313] [CITE@en[RFC 3875 - The Common Gateway Interface (CGI) Version 1.1]] ([TIME[2011-11-20 06:09:05 +09:00]] 版) <http://tools.ietf.org/html/rfc3875#section-6.3.2>
- [4] [CITE[OData Version 4.0 Part 1: Protocol Plus Errata 01]] ([TIME[2014-09-04 16:00:00 +09:00]] 版) <http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc370374813>
- [9] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-13.2>
- [37] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-14.9>
- [38] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-14.24>
]REFS]

* 意味

[425] [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]は、[[応答]]に関係ある[[資源]]を参照するものです。
その関係は[[要求メソッド]]と[[状態符号]]の意味の組み合わせにより決まります。 [SRC[>>424]]

[431] [CODE(HTTP)@en[[[201]]]] [[応答]]では、[[要求]]によって作成された主たる[[資源]]を指します
[SRC[>>424]]。

[432] [CODE(HTTP)[[[3xx]]]] [[応答]]では、自動的な[[リダイレクト]]で[RUBYB[好ましい]@en[preferred]]とされる[[対象資源]]を指します
[SRC[>>424]]。

;; [433] [CODE(HTTP)[[[3xx]]]] では [CODE(HTTP)@en[[[Location:]]]] を受信した[[利用者エージェント]]は自動的に[[リダイレクト]]することが期待されていますが、
[CODE(HTTP)[[[201]]]] では自動的な[[リダイレクト]]は期待されておらず、
単に[[リンク]]が示されるだけです。本来なら両者は別の[[ヘッダー]]とするべきだったでしょう。
([CODE(HTTP)[[[201]]]] は [CODE(HTTP)@en[[[Link:]]]] の方が適切だったでしょう。)

;; [438] [CODE(HTTP)@en[[[Content-Location:]]]] は[[応答]]に含まれる[[表現]]の
[[URL]] とされており、どちらの意味の [CODE(HTTP)@en[[[Location:]]]] とも異なるものです
[SRC[>>424]]。

* 構文

[426] [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]の値は、 [[RFC 3986]]
[[URI参照]]です。 [SRC[>>424]]

[FIG(railroad)[
= [[ASCII]] [[URL]]
]FIG]

;; [428] [[HTTPヘッダー]]では[[非ASCII文字]]は認められていません。

;; [430] [[絶対URL]]でも[[相対URL]]でも構いません。[[空文字列]]である[[相対URL]]も使えます。
過去には仕様上[[相対URL]]を認めていなかった時代もありましたが、
実情に合わせて現在は認められています。
(当時の名残で、[[HTTP応答]]生成用の[[ライブラリー]]などで[[応用]]が指定した[[相対URL]]から[[絶対URL]]に自動的に置き換えるものもあります。)

;; [429] [[素片識別子]]も使うことができます。

[435] [[素片識別子]]が適切で無い場面もあるとして、
[CODE(HTTP)[[[201]]]] を例に挙げています [SRC[>>424]] が、
なぜか禁止はされていません。また [CODE(HTTP)[[[201]]]]
以外にも不適切な場面が存在することを暗示していますが、
実際に何が該当するのかは不明です。

* 文脈

[417] [[起源鯖]]は、 [CODE(HTTP)@en[[[POST]]]]
[[要求]]の処理に成功して1つ以上の[[資源]]が作られた時には、
[CODE(HTTP)@en[[[201]]]] [[応答]]を送信する[['''べきです''']]。
[CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]に作成された主たる[[資源]]の [[URL]]
を含める[['''べきです''']]。[[表現]]は[[要求]]の状態と新しい[[資源]]への参照を説明したものとする[['''べきです''']]。
[SRC[>>412]]

[449] [[鯖]]が [CODE(HTTP)[[[300]]]] [[応答]]において[RUBYB[好ましい]@en[prefer]]選択肢を有する時は、
その [[URL]] を含む [CODE(HTTP)@en[[[Location:]]]] を[[生成]]する[['''べきです''']] [SRC[>>448]]。

[442] [[鯖]]は、 [CODE(HTTP)[[[301]]]]/[CODE(HTTP)[[[308]]]]
[[応答]]に [CODE(HTTP)@en[[[Location:]]]] 
[[ヘッダー]]を[[生成]]して新しい永続的
[[URL]] の好ましい [[URL]] を指定する[['''べきです''']] [SRC[>>441, >>2]]。

[444] [[鯖]]は、 [CODE(HTTP)[[[302]]]] [[応答]]や
[CODE(HTTP)[[[307]]]] [[応答]]に別の [[URL]] を含む 
[CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]を[[生成]]する[['''べき''']]です [SRC[>>443, >>447]]。

[446] [[鯖]]は、 [CODE(HTTP)[[[303]]]] [[応答]]では [CODE(HTTP)[[[Location:]]]]
[[ヘッダー]]で[[リダイレクト]]先の [[URL]] を指定します [SRC[>>445]]。

[420] [[起源鯖]]は、 [CODE(HTTP)@en[[[POST]]]]
[[要求]]の処理の結果が既存の[[資源]]の[[表現]]と等価である時には、
その [[URL]] を [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]に指定した
[CODE(HTTP)[[[303]]]] [[応答]]を送信することができます [SRC[>>412]]。

;; [440] なぜか仕様上 [CODE(HTTP)[[[201]]]] と [CODE(HTTP)[[[3xx]]]]
以外での [CODE(HTTP)@en[[[Location:]]]] の使用は禁止されていませんし、
その解釈も規定されていません。また [CODE(HTTP)[[[304]]]] でも禁止されていませんし、
どう解釈するべきかも不明です。

[6] [[OData]] は [CODE(HTTP)[[[202]]]] [[応答]]でも [CODE(HTTP)@en[[[Location:]]]]
[[ヘッダー]]を使っています。その場合指定された [[URL]] は処理対象の最新の状態を取得できる
[[URL]] とされています [SRC[>>4]]。

[27] [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]を複数指定することはできません。

* 処理

[427] [[相対URL]]が指定されている場合の[[基底URL]]は、
[[実効要求URL]]です [SRC[>>424]]。

[436] [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]に妥当な [[RFC 3986]]
[[URI参照]]以外が指定された時に[[回復]]しようとする[[受信者]]もありますが、
[[RFC 7231]] はそのような処理を強制も定義もしない、しかししても良い [SRC[>>424]]
とされています。

[437] 現実には [[RFC 3986]] [[URI参照]]でない [[URL]] を [CODE(HTTP)@en[[[Location:]]]]
[[ヘッダー]]に指定する[[鯖]] ([[Webアプリケーション]]など) は多々存在します。
[[利用者エージェント]]が[[Web互換]]であるためには、[[ヘッダー]]の値を
[[UTF-8]] により[[復号]]し、その結果を [[URL Standard]] 
に従い[[解決]]する必要があると思われます。

[422] [[利用者エージェント]]は、
[CODE(HTTP)[[[300]]]]
[CODE(HTTP)[[[301]]]], [CODE(HTTP)[[[302]]]], [CODE(HTTP)[[[303]]]],
[CODE(HTTP)[[[307]]]], [CODE(HTTP)[[[308]]]]
または未対応の [CODE(HTTP)[[[3xx]]]] の[[状態符号]]の[[応答]]に
[CODE(HTTP)@en[[[Location:]]]] があれば、
自動的に[[リダイレクト]]して構いません [SRC[>>448, >>441, >>443, >>421, >>445, >>447, >>2]]。

[26] [[利用者エージェント]]は、それ以外の[[応答]]で [CODE(HTTP)@en[[[Location:]]]]
が指定されていても自動的に[[リダイレクト]]してはいけません。

;; なぜか仕様上明確に規定されてはいませんが。

[451] [[リダイレクト]]の処理については、 [[HTTPリダイレクト]]の項を参照してください。

;; 無限の[[リダイレクト]]や[[素片識別子]]、 [[HTTP]]
以外のプロトコルへの[[リダイレクト]]、
[[fetch]]/[[navigate]]/[[レンダリング]]との関係などについてなどは[[HTTPリダイレクト]]の項を参照してください。

[3] [CODE(HTTP)@en[[[Location:]]]] の値は[[キャッシュ]]における[[非妥当化]]に使われることもあります。

[41] [CODE(HTTP)[[[207]]]] [[応答]]については、 [CODE(HTTP)[[[207]]]] も参照。

* CGI における [CODE(CGI)@en[Location:]] ヘッダー

[314] [[CGI]] では [CODE(HTTP)@en[[[Location:]]]] [[欄]]は [[CGI欄]]であり、[[CGIスクリプト]]が[[CGI応答]]に指定したものを[[鯖]]が解釈します。

[23] >>20 サーバー内 redirect を何度も繰り返し行うことも出来ます。 (HTTP Server は無限 loop にならないように対策する必要があるでしょう。)

[29] CGI で [CODE[Location:]] を使う時は、
[[Content-Type:]] 欄は不要なら出力しなくて構いません。
例えば、

[PRE[
 print <<EOH;
 Location: http://foo.example/bar[INS[(改行)]]
 [INS[(改行)]]
 EOH
]PRE]

というだけの出力の CGI script では
[SAMP[Content-Type: text/html]]
とか出力しなくてもいいです。 
(というかむしろ書いたら、1文字もない「空」では
HTML として成立しませんから不適当な指定となります。)

[34] CGI 欄は[[折り畳み]]が認められていないことにも注意が必要です。つまり

[PRE[
 Location:
   http://foo.example/
]PRE]

は HTTP では可能ですが、 CGI では不正です。
(まあ URI が値のこの欄ではしないとは思いますけどね。)

[315] [[CGI]] の [CODE(HTTP)@en[[[Location:]]]] 欄では
- [[絶対URL]] ([[URL scheme]] からはじまり、最大で[[素片識別子]]まで)
- [[絶対path]]と省略可能な[[query]]

... のいずれかの値を指定できます。前者の場合は[[クライアント・リダイレクト応答]]となり、
そのまま[[HTTP]] [CODE(HTTP)@en[[[Location:]]]] 欄となります。後者の場合は[[局所リダイレクト応答]]となり、
[[鯖]]が指定された [[path]] (と [[query]]) で[[要求]]を受け取ったものとして再処理します。
[SRC[>>313]]

[316] 両者の場合それぞれで、他の[[頭欄]]や[[応答本体]]の有無、それを受け取った[[鯖]]の処理が異なります。
詳しくはそれぞれの項をご参照ください。

* [CODE(XMLe)@en[location]] 要素 (WebDAV)

[24] [CODE(HTTP)[[[207]]]] [[応答]]に含まれる個別の[[状態符号]]が
[CODE(HTTP)[[[3xx]]]] である場合、[[鯖]]は [[HTTP]] [CODE(HTTP)[[[Location:]]]] 
[[ヘッダー]]のかわりに [CODE(XMLe)@en[[[location]]]] 
[[要素]]を使わなければ[['''なりません''']] [SRC[>>9, >>37]]。
[CODE(HTTP)[[[201]]]] の場合にも使えます [SRC[>>37]]。

[25] [[内容]]は、[[要素内容]]であり、 [CODE(XMLe)@en[[[href]]]]
[[要素]]1つです [SRC[>>37]]。 [CODE(XMLe)@en[[[href]]]] [[要素]]の[[内容]]が
[CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]の値に相当します
[SRC[>>37]]。

[39] [CODE(XMLe)@en[[[response]]]] [[要素]]の[[子要素]]として使うことができます [SRC[>>38]]。

;; [40] [CODE(XMLe)@en[[[propstat]]]] [[要素]]では認められていません。

[36] [[クライアント]]は、 [CODE(XMLe)@en[[[location]]]] [[要素]]が指定されることに依存しては[['''なりません''']]。
指定されなかった場合には、個別の[[資源]]に[[要求]]して[[リダイレクト]]先の [[URL]]
を得られないか試しても構いません。 [SRC[>>9]]

;; [35] この[[要素]]は [[RFC 2518]] にはなく、 [[RFC 4918]]
で追加されました。

* 歴史

[317] [CITE[WWW-Talk Jan-Mar 1994: Re: Redirection: "Location" or "Uri" ?]]
( ([TIME[2012-07-10 14:40:22 +09:00]] 版))
<http://1997.webhistory.org/www.lists/www-talk.1994q1/0216.html>

[FIG(quote)[
[FIGCAPTION[
[452] RFC 1945 (HTTP/1.0) 10.11; RFC 2068・2616 (HTTP/1.1) 14.30 Location
]FIGCAPTION]

> The Location response-header field [DEL[defines the exact location of the resource that was identified by the Request-URI]] [INS[is used to redirect the recipient to a location other than the Request-URI for completion of the request or identification of a new resource]]. [INS[For 201 (Created) responses, the Location is that of the new resource which was created by the request.]]
> For 3xx responses, the location [DEL[must]] [INS[SHOULD]] indicate the
server's preferred [DEL[[INS[{1945,2068}]] URL]] [INS[[INS[{2616}]] URI]] for automatic redirection to the resource. [DEL[Only one absolute URL is allowed.]] [INS[The field value consists of a single absolute [DEL[[INS[{1945,2068}]] URL]] [INS[[INS[{2616}]] URI]].]]

[5] [CODE[Location]] 応答頭欄は、要求の完了又は新しい資源の特定のために
[[Request-URI]] 以外の場所に受信者を[RUBY[再指向] [リダイレクト]]するのに使います。
[[201]] (Created: 作成。) 応答では、 [CODE[Location]]
は要求により作られた新しい資源の場所です。
3[VAR[x]][VAR[x]] 要求では、この場所は、資源への自動誘導のための、サーバー側的により好ましい
URI を示します。
欄の値は単一の絶対 URI で構成します。

>
- Location       = "Location" ":" absoluteURI [INS[[INS[{Errata}]] [ "#" fragment ] ]]

[INS[

訳注: Errata の件について [[HTTPリダイレクト]>>35] を参照。
]INS]

> An example is[INS[: [INS[{2616}]]]]

例:

>
- [DEL[Location: http://www.w3.org/hypertext/WWW/NewLocation.html]]
- [INS[Location: http://www.w3.org/pub/WWW/People.html]]

[INS[

> Note: The Content-Location header field (section [DEL[14.15]] [INS[14.14]]) differs
from Location in that the Content-Location identifies the original
location of the entity enclosed in the request. It is therefore
possible for a response to contain header fields for both Location
and Content-Location. Also see section 13.10 for cache requirements
of some methods.

[8] '''注意''': [CODE(HTTP)[[[Content-Location]]]]
頭欄は [CODE[Location]] とは異なり、要求に同封された実体の場所を識別します。
従って、応答に [CODE[Location]] と 
[CODE[Content-Location]] の双方を含めることも可能です。
幾つかの方式のキャッシュ要求について、 13.10
節も参照。
]INS]

[INS[

注: 注記のない修正は、 RFC 1945→2068 での変更箇所。
]INS]
]FIG]

[FIG(quote)[
[FIGCAPTION[
[453] HTTP CGI/1.1 (draft 03) 7.2 (抜粋)
]FIGCAPTION]

> At least one CGI-Field
MUST be supplied, but no CGI field name may be used more than
once in a response. If a body is supplied, then a
"Content-type" header field MUST be supplied by the script,
otherwise the script MUST send a "Location" or "Status" header
field. If a Location CGI-Field is returned, then the script
MUST NOT supply any HTTP-Fields.

[33] 最低1つの CGI 欄を供給しなければ'''なりません'''。
但し同じ CGI 欄名を1つの応答中に複数使ってはいけません。
[[本体]]を供給する場合、 script は「Content-type」
頭欄を供給しなければ'''なりません'''。
そうでない場合 [INS[(本体を供給しない場合)]] script は
は「Location」頭欄か「Status」頭欄を送らなければ'''なりません'''。
[CODE[Location]] CGI 欄を返す場合、 script はどの HTTP
欄も供給しては'''いけません'''。


** 7.2.1.2. Location

> This is used to specify to the server that the script is
returning a reference to a document rather than an actual
document.

[10] これは、サーバーに対してスクリプトが実際の文書ではなく文書への参照を返すことを指定するのに使います。   
- [11] Location         = "Location" ":" ( fragment-URI | rel-URL-abs-path ) NL
- [12] fragment-URI     = URI [ # fragmentid ]
- [13] URI              = scheme ":" *qchar
- [14] fragmentid       = *qchar
- [15] rel-URL-abs-path = "/" [ hpath ] [ "?" query-string ]
- [16] hpath            = fpsegment *( "/" psegment )
- [17] fpsegment        = 1*hchar
- [18] psegment         = *hchar
- [19] hchar            = alpha | digit | safe | extra | ":" | "@" | "& | "="

> The Location value is either an absolute URI with optional
fragment, as defined in RFC 1630 [1], or an absolute path
within the server's URI space (i.e., omitting the scheme and
network-related fields) and optional query-string. If an
absolute URI is returned by the script, then the server MUST
generate a '302 redirect' HTTP response message unless the
script has supplied an explicit Status response header field.
Scripts returning an absolute URI MAY choose to provide a
message-body. Servers MUST make any appropriate modifications
to the script's output to ensure the response to the
user-agent complies with the response protocol version. If the
Location value is a path, then the server MUST generate the
response that it would have produced in response to a request
containing the URL
[PRE[
   
-[21] scheme "://" SERVER_NAME ":" SERVER_PORT rel-URL-abs-path
]PRE]

[20] [CODE[Location]] 値は、 [[RFC1630]] で定義されている絶対
URI 及び省略可能な[[断片]]か、又はサーバーの URI
空間内の絶対経路 (すなわち、[[scheme]] とネットワーク関連欄を省略したもの。)
及び省略可能な [[query-string]] のいずれかです。
絶対 URI が script により返された場合、サーバーは、
[CODE[Status]] 応答頭欄が明示的に指定されていない限り、
「[[302]] redirect」 HTTP 応答メッセージを生成しなければ'''なりません'''。
絶対 URI を返す script は [[message-body]]
を提供することを選んでも'''構いません'''。
サーバーは、[[利用者エージェント]]への応答が応答のプロトコルの版に合致することを確実にするため、
script の出力を適当に修正しなければ'''なりません'''。
[VAR[Location]] 値が経路である場合、サーバーは >>21 の [[URL]]
を含む要求への応答であるとして応答を生成しなければ'''なりません'''。

> Note: If the request was accompanied by a message-body (such
as for a POST request), and the script redirects the request
with a Location field, the message-body may not be available
to the resource that is the target of the redirect.

[22] '''注意''': 要求が [CODE(ABNF)[message-body]]
を伴っていて ([[POST]] 要求の場合など)、
script が要求を [CODE[Location]] 欄で redirect
した場合、 redirect の対象の資源には [CODE(ABNF)[message-body]]
は利用可能でないかもしれません。
]FIG]

** 00年代の実装

[45] 噂によると [[tok2]] では広告の関係で CGI header [CODE(CGI)[Location:]] が使えないらしいです。

[46] >>45 トクトクは CGI 使えますと宣伝していましたよね。本当だとしたら虚偽広告ということになります。やめていただきたいね。

[28] サーバーによっては [[Cookie]] と相性が悪いようです。 (''CGIでクッキーセットした後にLocationで他のURLに飛ばしたいんですが・・・'' <http://tohoho.wakusei.ne.jp/lng/199908/99080130.htm>) (([CODE[200]] の [[HTML]] 文書以外では Cookie は使わない方が良いですね。色々の実装状況的に。))

[50] >>28 これ、 [CODE(CGI)[Location]] と [CODE(HTTP)[[[Set-Cookie]]]] を併用すると
[[IIS]] 3.0 や [[PWS]] では上手くいかない、 [[Apache]]
では上手くいく、ということですけど、こんなことってあり得ますかね?

Redirect 前と redirect 後の扱いで UA 側で不具合 (あるいは仕様)
によって上手くいかない可能性は大いにあると思うのですけど、
それならどのサーバーでも上手くいかないはずです。 [CODE(CGI)[Location]]
あるいは [CODE(HTTP)[[[3xx]]]] 使用時に [CODE(HTTP)[Set-Cookie]]
を捨てるような設計に IIS がなっているとすればこの挙動になるのでしょうけど、
そんな設計するような根拠が思いつかない。

もっとも、 >>28 のやりとりは話してる内容が大雑把過ぎて何ともいえませんよね。
誰かがちゃんと確かめた方がいいと思いますけど、今時 IIS なんて使ってる人いますか?

[59]
修正パッチなしの[[なつみかん]]には[CODE(HTTP)@en[[[Content-Location]]:]] 欄
(など[CODE(HTTP)@en[Location]]が含まれる[[頭欄]]を[CODE(HTTP)@en[[[Location]]:]]
欄と誤認する不具合があります。

[CITE[ねこめしにっき(2006年1月)]] 
<http://www.remus.dti.ne.jp/~a-satomi/nikki/2006/01a.html?01090700#d08n01>

([[名無しさん]] [WEAK[2006-01-09 08:22:59 +00:00]])

** 飛び先で文字化け問題

[30] 古い [[NC]]4 などで、

[PRE[
 Content-Type: text/html; charset=iso-8859-1
 Location: http://foo.example/bar/
]PRE]

と言われて、 [SAMP[http://foo.example/bar/]] を取り寄せると

[PRE[
 Content-Type: text/html
]PRE]

であって中身が日本語の漢字かな混じり文とかの時に、[[文字コード]]自動判別が行われずにそのまま
[[ISO-8859-1]] と認識され、[[文字化け]]するという問題が起きました。

[31] この問題で一番悪いのは、 [[ISO-8859-1]] 以外の文書に
[[charsetパラメーター]]を付けずに送り出す相手サーバーです。

[[Apache]] 1.3.12 で >>30 の上の例のように、エラー・メッセージで必ず
[CODE[charset]] パラメーターをつけるように修正された
(安全性の問題への対処のため。) ことで、正しい [CODE[charset]]
パラメーターを HTML 
文書につけて送らない日本語文書が主のサーバーで広範囲で問題が起こりました。
問題の直接的な原因となった 1.3.12 の修正を元に戻すことで対策を行ったところやそれを薦める人もいましたが、それは'''間違っています'''。

[55] きっとこの問題って、リンク先の頁もきっとリンク元の頁と同じ
[CODE(MIME)[charset]] であることが多いだろうなあ、
利用者のために補完したるか、っていう親切心で実装したんでしょうねぇ。

だとしたら Netscape の開発者を責めるのは可哀想かもしれない。

もちろん責められるべきは [CODE(MIME)[charset]] 引数の値を正しく設定できないサーバー管理者のあなたです。20世紀にはそれが許されましたが、21世紀には許されませんよ。

** ブラウザのアドレス表示

[56] [CODE(HTTP)[Location:]] 欄に不正な文字列を指定したとします。
例えば、
[SAMP(HTTP)[Location: http://invalid%3A80/]]
を含む redirect 応答を返したとします。

[57] このとき、 [[WinIE6]] では、
サーバーに接続できませんという画面になりますが、
そのアドレス棒の URI は redirect
前のものになったままです。
飛ぼうとした redirect 先 URI
は画面のどこにも出てきません。

つまり、 redirect 元の鯖には正しく接続できて応答ももらっているくせに、
その応答がいかれているがために、
その鯖にすら接続できなかったかのような紛らわしいメッセージが表示されてしまうのです。

** 素片識別子

[454] [[HTTPリダイレクト]]を参照してください。

** 相対 URL

@@ ...

** RFC 723x

[318] [CITE[#185 (Location header payload handling) – httpbis]]
( ([TIME[2012-07-10 14:44:09 +09:00]] 版))
<http://trac.tools.ietf.org/wg/httpbis/trac/ticket/185>

[329] [CITE@en[draft-ietf-httpbis-p2-semantics-22 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]]
( ([TIME[2013-05-03 02:04:10 +09:00]] 版))
<http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-22#section-7.1.2>

[455] しかし [[RFC 723x]] でも未解決の問題がいくつも指摘されています。

[REFS[
- [410] [CITE@en[HTTP - WHATWG Wiki]]
( ([TIME[2013-12-19 01:12:07 +09:00]] 版))
<http://wiki.whatwg.org/wiki/HTTP#Location_header>
]REFS]

[411] [CITE@en[RFC 7252 - The Constrained Application Protocol (CoAP)]]
( ([TIME[2014-06-27 00:59:37 +09:00]] 版))
<http://tools.ietf.org/html/rfc7252#section-5.10.7>

* 実装

[43] [[Google BigQuery]] は [CODE(HTTP)[[[200]]]] で [CODE(HTTP)@en[[[Location:]]]]
を使っています [SRC[>>42]]。

[REFS[
- [42] [CITE@ja[Loading Data with a POST Request - Google BigQuery — Google Cloud Platform]] ([TIME[2014-12-18 02:33:03 +09:00]] 版) <https://cloud.google.com/bigquery/loading-data-post-request#save-session-uri>
]REFS]

* 関連

[49] [[HTTP]] で、関連するプロトコル要素:
- [CODE(ABNF)[[[Request-URI]]]]
- [CODE(HTTP)[[[Content-Location]]:]] 欄
- 状態符号 [CODE(HTTP)[[[201]] (Created)]]
- 状態符号群 [CODE(HTTP)[[[3xx]]]]

[32] [[w3m]] の [[LocalCGI]] 機能で似たようなものとして 
[CODE(CGI)[[[w3m-Control]]:]] 欄 + [CODE[GOTO]] があります。
[SAMP[w3m-control: GOTO file:///cgi-bin/foo.cgi]] のように使います。

[7] [[SSDP]] の [CODE(HTTP)@en[[[LOCATION:]]]] [[ヘッダー]]とは意味が異なります。

[44] [CITE[WWW-Talk Jan-Mar 1994: Re: Redirection: "Location" or "Uri" ?]]
([TIME[2015-01-25 12:39:25 +09:00]] 版)
<http://1997.webhistory.org/www.lists/www-talk.1994q1/0221.html>

[FIG(quote)[
[FIGCAPTION[
[47] [CITE@en[Draft: PubSubHubbub Core 0.4 -- Working Draft]]
([TIME[2015-03-16 20:33:17 +09:00]] 版)
<https://pubsubhubbub.googlecode.com/git/pubsubhubbub-core-0.4.html#anchor6>
]FIGCAPTION]

> If (and when), the subscription is denied, the hub MUST inform the subscriber by sending an HTTP '''['''RFC2616''']''' GET request to the subscriber's callback URL as given in the subscription request. 
> Hubs may provide an additional HTTP '''['''RFC2616''']''' Location header (as described in section 14.30 of Hypertext Transfer Protocol '''['''RFC2616''']''') to indicate that the subscriber may retry subscribing to a different hub.topic. This allows for limited distribution to specific groups or users in the context of social web applications.

]FIG]


[48] [CITE[Kolejny XSS w www.google.com (Custom Search Engine)]]
([TIME[2015-04-08 19:02:40 +09:00]] 版)
<http://sekurak.pl/kolejny-xss-w-www-google-com-custom-search-engine/>

[51] [CITE@en[Fix #111: forbid redirects to data URLs · whatwg/fetch@f986c43]]
([TIME[2015-09-23 13:41:40 +09:00]] 版)
<https://github.com/whatwg/fetch/commit/f986c43f958a0f7ffdc46553d5a53a0c56a89a32>

[52] [CITE@en[655389 – CRLF Injection and the parsing of HTTP headers]]
([TIME[2015-10-05 20:57:47 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=655389>

[53] [CITE@en[Merge URLUtils into Location · whatwg/html@f0a7365]]
([TIME[2015-10-07 13:59:04 +09:00]] 版)
<https://github.com/whatwg/html/commit/f0a73659b4046cc35a28855f3544dead66345689>

[54] [CITE@en[Defining exotic objects in IDL, HTML, or both?]]
([[Anne van Kesteren]] 著, [TIME[2015-10-12 21:45:31 +09:00]] 版)
<https://lists.w3.org/Archives/Public/www-archive/2015Oct/0009.html>

[58] [CITE@en[annevk/html-cross-origin-objects]]
([TIME[2015-10-20 21:03:23 +09:00]] 版)
<https://github.com/annevk/html-cross-origin-objects>

[60] [CITE@en[1142083 – IDN Unicode domain redirect is broken in Firefox 36/37/38]]
([TIME[2015-11-06 18:14:58 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=1142083>

[61] >>60 <http://zymiausifotografai.lt/>
>
[PRE(HTTP code)[
HTTP/1.1 301 Moved Permanently
Date: Fri, 06 Nov 2015 09:15:23 GMT
Server: Apache
Location: http://www.Å¾ymiausifotografai.lt
Vary: Accept-Encoding
Content-Length: 312
Connection: close
Content-Type: text/html; charset=iso-8859-1
]PRE]


[62] [CITE@en[Add some more parameters to the "perform a security check" hook (for … · heycam/webidl@adf3772]]
([TIME[2016-01-14 15:20:12 +09:00]] 版)
<https://github.com/heycam/webidl/commit/adf37720bd92138f9f1627a214330287550c0004>

[63] [CITE@en[29383 – Need a way to define toJSON, valueOf, @@toPrimitive]]
([TIME[2016-01-30 12:12:31 +09:00]] 版)
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=29383>

[64] [CITE@en[27361 – ''''''[''''''Unforgeable'''''']'''''' and "''''''[''''''''''''[''''''Enumerable'''''']'''''''''''']'''''': true"]]
([TIME[2016-01-30 12:13:27 +09:00]] 版)
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=27361>

[65] [CITE@en[29183 – Objects that implement an ''''''[''''''Unforgeable'''''']'''''' interface should have a non-configurable @@toPrimitive method]]
([TIME[2016-01-30 12:13:59 +09:00]] 版)
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=29183>

[66] [CITE@en[annevk/html-cross-origin-objects]]
([TIME[2016-02-01 22:37:43 +09:00]] 版)
<https://github.com/annevk/html-cross-origin-objects>

[67] [CITE@en[URLs are parsed and produce records · whatwg/html@30bc255]]
([TIME[2016-02-14 23:02:53 +09:00]] 版)
<https://github.com/whatwg/html/commit/30bc2557105ad62881ec9670f253febbc9761b44>

[68] [CITE@en[Fix #212: redirects parse Location headers against the response's url · whatwg/fetch@a8c5f4d]]
([TIME[2016-02-16 11:22:50 +09:00]] 版)
<https://github.com/whatwg/fetch/commit/a8c5f4d0fc712573383873e1d7a4aa3a2ad9c392>

[69] [CITE@en[Acknowledge Bobby Holley for Window/Location security design · whatwg/html@20f97a2]]
([TIME[2016-02-28 21:29:43 +09:00]] 版)
<https://github.com/whatwg/html/commit/20f97a2aebfff007d56f6310d6d5caa96b98329d>

[70] [CITE@en[Define security around Window, WindowProxy, and Location properly · whatwg/html@acae3df]]
([TIME[2016-03-13 23:32:37 +09:00]] 版)
<https://github.com/whatwg/html/commit/acae3df652b382e9f4f1d1b4dc7e08e2b00df821>

[71] [CITE@en[Give response a location URL for reuse in HTML]]
([[annevk]]著, [TIME[2016-06-27 23:36:30 +09:00]])
<https://github.com/whatwg/fetch/commit/8d922d9178cbcab296ca3b3a76a775949e3a87a8>

[72] [CITE@en[Editorial: cleanup prior commit]]
([[annevk]]著, [TIME[2016-06-28 00:11:48 +09:00]])
<https://github.com/whatwg/fetch/commit/2db24f3d97fc57c14eb133d3a41ecdc55409aa00>

[73] [CITE@en[Navigate: remove "gone async" and define redirect handling]]
([[annevk]]著, [TIME[2016-07-04 17:38:20 +09:00]])
<https://github.com/whatwg/html/commit/8b630f5e4fa2ec8b0999470d09490bffe6e9a1e3>

[74] [CITE@en[22654 – Duplicate Location headers]]
([TIME[2016-08-25 12:05:23 +09:00]])
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=22654>

[75] [CITE@en[Preventing some CRLF header injection attacks · Issue #375 · whatwg/fetch]]
([TIME[2016-08-25 12:05:32 +09:00]])
<https://github.com/whatwg/fetch/issues/375>

[FIG(quote)[
[FIGCAPTION[
[76] [CITE@en[Micropub]]
([TIME[2017-05-21 23:18:57 +09:00]])
<https://micropub.net/draft/#feature-li-16>
]FIGCAPTION]

> Returning HTTP 202 Created and a Location header when creating a post

]FIG]


[FIG(quote)[
[FIGCAPTION[
[77] [CITE@en[Micropub]]
([TIME[2017-05-21 23:18:57 +09:00]])
<https://micropub.net/draft/#response-p-1>
]FIGCAPTION]

> When the post is created, the Micropub endpoint must return either an HTTP 201 Created status code or HTTP 202 Accepted code, and must return a Location header indicating the URL of the created post. '''['''RFC2616''']'''

]FIG]


[FIG(quote)[
[FIGCAPTION[
[78] [CITE@en[Compromise On Checkout - Vulnerabilities in SCM Tools · The Recurity Lablog]]
( ([TIME[2017-08-15 02:20:25 +09:00]]))
<http://blog.recurity-labs.com/2017-08-10/scm-vulns>
]FIGCAPTION]

> After double checking, it could be confirmed that SVN was affected in the worst way: SVN follows HTTP 301 redirects to svn+ssh:// URLs. As a result, an innocent looking HTTP URL can be used to trigger a Command Execution with a 301 redirect.

]FIG]


[79] [CITE@en[RFC 4437 - Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources]]
([TIME[2017-09-24 19:11:37 +09:00]])
<https://tools.ietf.org/html/rfc4437#section-5>

[80] [CITE@en[Editorial: replace UTF-8 encode with isomorphic encode]]
([[annevk]]著, [TIME[2018-05-28 21:03:01 +09:00]])
<https://github.com/whatwg/fetch/commit/ffbaefb5c4f68b9d619e9db6491fd665a30a2ffb>

[81] [CITE@en[Editorial: replace UTF-8 encode with isomorphic encode by annevk · Pull Request #742 · whatwg/fetch]]
([TIME[2018-06-02 09:00:52 +09:00]])
<https://github.com/whatwg/fetch/pull/742>

[82] [CITE@en[Request-URIのパスからのオープンリダイレクト · GitHub]]
([TIME[2019-01-09 16:39:44 +09:00]])
<https://gist.github.com/atsunoda/5c6e7a4ab35e7cbda2cdd4b292d9a573>