[2] 3xx
応答で他の URL を指定し、利用者エージェントにその
URL に要求を送信することを求めること、あるいはそのような応答のことを、
リダイレクトといいます。
[305] HTTPリダイレクトは、次のプロトコル要素により構成されます。
[33] 著者 (Webアプリケーション開発者) は、 リダイレクトで使うべき状態符号を次のように決定できます。
[14] リダイレクトは、対象資源のかわりに、別の URL にアクセスするべきであることを表しています。
[15] その実際の意味は様々です。301
が最適な状態符号ですが、 302
となっていることも多々あります。POST
を処理した後に、処理が反映されているページやその他関連するページなど、
POST
操作の完了後に利用者に提示するべきページに遷移させるためによく使われます。
302
がよく用いられます。404
のかわりにトップページなどにリダイレクトすることがあります。
ただしこの動作は URL の打ち間違いでも遷移してアドレスバーが書き換わってしまうなど、
利用者には不評で最近はあまり使われなくなっています。401
や 403
や 404
を使うべきなのでしょうが、利用者の便宜その他の理由でしばしば使われています。303
リダイレクトを使うことになっています。
[539] 新旧の要求と応答は、互いに完全に独立したものです。 HTTP プロトコルとしては状態は保持していません。新旧要求を異なる HTTP接続を使って送信しても何ら問題ありませんし、 新旧要求の送信先の鯖がそもそも異なっているかもしれません。
[538] Location:
ヘッダーには相対URL
を指定することもできます。この値は実効要求URLを基底URL
として解決されます。
Location:
を参照。[11] 301
と 302
では、
POST
だった場合リダイレクト先では
GET
に書き換えます >>56。それ以外の要求メソッドはそのまま保持します。
[12] 303
では、リダイレクト先では
GET
に書き換えます >>56。
[13] 307
と 308
では、
リダイレクト先でもリダイレクト前の要求メソッドをそのまま保持します。
[307] 要求メソッドが安全でない場合、自動的なリダイレクトには注意する必要があります。 利用者は安全でない要求をリダイレクトしてほしくないかもしれません。 >>306
[308] Location:
があれば、
未対応の 3xx
状態符号であっても、
自動的にリダイレクトして構いません >>306。
[517] 起源鯖は、 PUT
要求に対して対象資源の状態を変更せず、
他の資源に適用したい場合は、
適切な 3xx
応答を送信しなければなりません。
その場合利用者エージェントはリダイレクトに従うか選ぶことができます。 >>518
[98]
HTTPクライアントによってはリダイレクト後の要求メソッドが
Webブラウザーと違った挙動になることがあります。
初期 HTTP 仕様の迷走と関係しているのですが、
クライアントによって動作が違うのは困ったものです。
新しいクライアントは Web互換性のために
Webブラウザー (Fetch Standard) と同じ動作を実装するべきです。
[7] リダイレクト前後で指定するべきヘッダーの同一性や差異について特に規定はありません。
[8] RFC 7231 はヘッダーの仕様書に対し、リダイレクト前後で保持するべきか明記することを検討するよう求めています >>6。
[540] 素片識別子が適切で無い場面もあるとして、
201
を例に挙げています >>534 が、
なぜか禁止はされていません。また 201
以外にも不適切な場面が存在することを暗示していますが、
実際に何が該当するのかは不明です。
[537] 利用者エージェントは、3xx
応答の
Location:
に素片識別子が含まれていない場合、
要求対象を生成するのに使ったURLの素片識別子を継承するものとして処理しなければなりません
>>534。
[41] http://foo.example/bar#fragment1 を取り寄せる時に、次のようになったとします。
C: GET /bar HTTP/1.1 C: Host: foo.example C: S: 302 Found HTTP/1.1 S: Location: http://foo.example/hoge S:
この時、 UA の望ましい動作は、 (WWWブラウザであれば) http://foo.example/hoge を要求し、その #fragment1 を表示することです。
[42] 同じ例で、次のような応答があったとしましょう。
S: 302 Found HTTP/1.1 S: Location: http://foo.example/hoge#fragment2 S:
この時 WWW ブラウザは、 http://foo.example/hoge#fragment2 を表示し、 #fragment1 のことは忘れます。
[44] >>42 で、「アドレス・バー」のような UI 部分をどうするかという問題がありますね。 301 なら新しい (#fragment2 の) URI にしてしまえばいいですが、 307 の時はどうなんでしょう。元の #fragment1 にしておくのと、 #fragment* は削ってしまうのと2種類考えられますが。
[43] 但し実際には、この #fragment の扱いについては仕様・実装がぐちゃぐちゃです。
できることならば Location
欄で素片識別子を使わないといけないようなことにならないようによく考えておくべきでしょう。それでも使わざるを得なくなったときは仕方ないですし、 UA の挙動なんて飾りです、偉い人には分からなくて結構と開き直るのも場合によってはありでしょう。
[24] >>20,>>5 RFC2396 (URI) によると absoluteURI
は fragment
を含みません。従って HTTP/1.1 と CGI で仕様が不整合な気がします。
実際のところ fragment
つき URI を送っても多くの URI は解釈する気がしますが、仕様的には無理ということでいいですか?
[35] >>24 HTTP/1.1 Specification Errata http://world.std.com/~lawrence/http_errata.html#location-fragments http://purl.org/NET/http-errata#location-fragments
に載ってました。 (こんなの知らなかった。) >>6
の通り、 HTTP でも URI の後に #fragment をつけることが出来ます。
[36] とはいえ、知らない実装者も居るだろうな。。。要注意ですね。
There are circumstances in which a fragment identifier in a Location URL would not be appropriate:
- With a 201 Created response, because in this usage the Location header specifies the URL for the entire created resource.
- With a 300 Multiple Choices, since the choice decision is intended to be made on resource characteristics and not fragment characteristics.
- With 305 Use Proxy.
At present, the behavior in the case where there was a fragment with the original URI, e.g.: http://host1.example.com/resource1#fragment1 where /resource1 redirects to http://host2.example.com/resource2#fragment2 is 'fragment1' discarded? Do you find fragment2 and then find fragment1 within it? We don't have fragment combination rules.
Location
URL 中での素片識別子が適切でない場面があります。
Location
頭を使用して作成された資源全体を URL を指定するものだから。現在、元の URI に素片がある場合、例えば http://host1.example.com/resource1#fragment1 で /resource1 が http://host2.example.com/resource2#fragment2 に redirect している時に「fragment1」は捨てられているのでしょうか? fragment2 を探してそれから fragment2 を探すのでしょうか? 我々は素片組み合わせ規則は持っていません。
[38] >>37 の後半の問題、実際のところどうなんだろう? どっちにしる!とも言いがたいよなあ。
[39] Common User Agent Problems: Handle the fragment identifier of a URI when the HTTP request is redirected. http://www.w3.org/TR/cuap#cp-fragment
この W3C NOTE は、 #fragment に対応していない UA があるけどちゃんとしる! と言うと共に、 >>37-38 問題について、 #fragment2 にしる! と言っています (小文字 must)。
[310] Web Applications 1.0 r6322 Make Facebook work. See http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx ( ( 版)) http://html5.org/tools/web-apps-tracker?from=6321&to=6322
[311] URL Fragments and Redirects - EricLaw's IEInternals - Site Home - MSDN Blogs ( ( 版)) http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx
[312] draft-bos-http-redirect-00 - Handling of fragment identifiers in redirected URLs ( 版) http://tools.ietf.org/html/draft-bos-http-redirect-00
[10] RFC 7231 は、リダイレクトによって元の URL に指定されていた素片識別子をリダイレクト先の URL の文書が読み取れることによる情報漏洩の危険があることを指摘しています >>9。
[58]
WinIE 6.0 (もしかしたら以前の版も。) は redirect された時の Location
URI 参照に素片識別子がついていると直後の再要求時にその素片識別子ごと Request-URI
にして送ってしまうみたいです。
(名無しさん 2004-05-03 04:37:14 +00:00)
[543] HTTPリダイレクトは、応答の直後にリダイレクト後の要求が送信されることを期待しています。
[544] 仕様上は応答から要求までの待ち時間を Retry-After:
ヘッダーで指定できることになっていますが、実装されていませんし、
今後実装される見込みもなさそうです。
[545] 一旦何らかのページを表示して、すこし待ってから別のページを表示したいときは、
Refresh
を利用できます。
[309] WinIE8、Opera、Chrome、Firefox のどの Webブラウザーも、 リダイレクトしている HTTPメッセージ全体が到着するのを待たず、 頭部を受け取り次第すぐにリダイレクト先の URL の取得をはじめるようです。
[68] Set request’s referrer policy on redirect は、
要求と応答について次のようにします >>67。
[100] まきのっぴさんはTwitterを使っています: 「そこで「それリダイレクト設定どこに書きました? .htaccessに書いてない? でしょ? じゃあhttpd.confに書いて再検証してみて」と指示してやり直した結果、許容し得る性能低下で済むようになったとの報告があり、数万行のリダイレクト設定を施したリニューアルが無事実現できました。」 / Twitter, , https://twitter.com/pmakino/status/1642930069403484160
[99] tecklさんはTwitterを使っています: 「ちなみにNginxでリダイレクトさせた時は、起動時にメモリを食うものの速度自体は普通に高速でした。 その後リダイレクト件数が200万件?を超えてきてメモリも厳しくなったので Nginx + Go + SQLiteの動的リダイレクトに切り替えたら超省メモリになりました(便乗宣伝) https://t.co/PCPSVmJNBo」 / Twitter, , https://twitter.com/teckl/status/1643101178165878784
[519] リダイレクトには、元々の要求の要求対象を書き換え、
要求メソッドを維持するパターンと、要求メソッドを GET
に書き換えるパターンがあります。
[520] HTTP 仕様書の著者の意図は、 301
と 302
は前者とするものでしたが (CERN の実装もそうなっていました)、
実際には 303
共々後者の動作とする実装があり、
やがて後者に収束していきました。 >>306
[521] このため後者の意味の 307
が新たに追加されました。
更に、要求メソッドが POST
だった場合のみ、
301
と 302
で前者の動作でも適合することとされました。
>>306
301
と 302
は元の要求メソッドのままリダイレクトするのが正しい使い方のようです。
15年以上にわたり安定している現在の慣習と互換性のない“理論上は正しい”
方式にこだわり続ける意図が何なのかは謎です。 Webブラウザーも鯖側の
Webアプリケーションも、 301
や 302
で要求メソッドが保持されることなど想定しておらず、
そうでない実装方法は決してWeb互換では無いのですが・・・。[1] リダイレクトの設定とインデックスに登録されるURL - インフォセンター - Yahoo!検索 ( 版) http://info.search.yahoo.co.jp/archives/002865.php
[3] 通常は HTTPリダイレクトとは呼びませんが、 Refresh:
ヘッダー (や <meta http-equiv=refresh>
)、
HSTS もリダイレクトを実現するものです。
[4] またリダイレクトには JavaScript によってクライアント側で実行する手法もあります。
[5] HTTP の仕様書は、 300
や 304
もリダイレクトと呼んでいます。
3xx
の項を参照。[542] 201
でも Location:
を使いますが、本項のHTTPリダイレクトとは異なります。
[541] HTTP には他に Content-Location:
や
Link:
もありますが、本項の HTTPリダイレクトとは異なります。
[526] CGI には局所リダイレクト応答とクライアントリダイレクト応答がありますが、 クライアントリダイレクト応答がHTTP応答におけるリダイレクトに相当します。
[27] Referrer によってリンク元が送信されてしまうことを防ぐため、
本来のリンク先との中間に1ステップ挟む“中間ページ”型リンクも、
広義のリダイレクトと言えます。 Refresh
や
location.href
と併用することで中間ページを設けつつ自動でリンク先に遷移させる本当のリダイレクトになっている場合もあります。
[28] ガラケーのようなリダイレクト回数の制限の厳しい利用者エージェントとの互換性のため、 敢えてHTTPリダイレクトを使わずに >>27 のような中間ページを使うこともあります。
[527] Response.redirect() > new RedirectResponse() · a083a27 · whatwg/fetch ( ( 版)) https://github.com/whatwg/fetch/commit/a083a27c53a65e5ba93c486401fb55c2a68a7cd3
[528] HTTP - WHATWG Wiki ( ( 版)) http://wiki.whatwg.org/wiki/HTTP#Redirects
[529] HTTP Methods and Redirect Status Codes - IEInternals - Site Home - MSDN Blogs ( ( 版)) http://blogs.msdn.com/b/ieinternals/archive/2011/08/19/understanding-the-impact-of-redirect-response-status-codes-on-http-methods-like-head-get-post-and-delete.aspx
[530] 598304 – XHR rewrites non-POST methods upon 301/302 redirects ( ( 版)) https://bugzilla.mozilla.org/show_bug.cgi?id=598304
[531] 676059 – Make redirect prompting depend on HTTP-safeness of method, not presence of request body ( ( 版)) https://bugzilla.mozilla.org/show_bug.cgi?id=676059
[532] Test Cases for HTTP Redirects ( ( 版)) http://greenbytes.de/tech/tc/httpredirects/
[533] Bug 60440 – [Qt] Redirection of HTTP POST (3xx) incorrectly includes original POST data ( ( 版)) https://bugs.webkit.org/show_bug.cgi?id=60440
[330] au のガラケーだと素片識別子が入っていると 404
になります。
[406] Location: javascript:alert(1) が返ってきた時のブラウザの動作 - Qiita [キータ] ( ( 版)) http://qiita.com/ooooooo_q/items/1f0c2c64413495c46e6b
[410] HTTP - WHATWG Wiki ( ( 版)) http://wiki.whatwg.org/wiki/HTTP#Location_header
[423] URL Fragments and Redirects - IEInternals - Site Home - MSDN Blogs ( ( 版)) http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx
[29] Refactor manual redirect flag into redirect mode. Preparation for https:... · whatwg/fetch@8398149 ( 版) https://github.com/whatwg/fetch/commit/83981498175633510878ebf97077ec632ceedc29
[30] Provide limited control over redirects. Fixes https://www.w3.org/Bugs/Pu... · whatwg/fetch@b6b4f87 ( 版) https://github.com/whatwg/fetch/commit/b6b4f87048020cda6237ca4af02df62d43f99765
[31] 598304 – XHR rewrites non-POST methods upon 301/302 redirects ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=598304
[32] Certain redirects rewrite the request method. Fixes #32 · whatwg/fetch@a8e07c8 ( 版) https://github.com/whatwg/fetch/commit/a8e07c886198e85ca3eb757f3ef284193da11a0f
[61] Put redirect statuses in a shorthand. · whatwg/fetch@bd284d1 ( 版) https://github.com/whatwg/fetch/commit/bd284d112e207c900c61d90c8bd005a4b6e1d687
[63] POSTリクエストをリダイレクトするとGETされる?POSTされる? - はこべブログ ♨ ( 版) http://hakobe932.hatenablog.com/entry/20090707/1246985195
[64] Fix #187: set body to null when method is set to `GET` in a redirect · whatwg/fetch@379daf2 ( 版) https://github.com/whatwg/fetch/commit/379daf2b451b026f5fe2012da2f6e01ceccb3b58
[65] Revert #111: allow redirects to data URLs · whatwg/fetch@31f65e4 ( 版) https://github.com/whatwg/fetch/commit/31f65e4625eacb3a74b5d1eba905d0600040c6ce
[66] Allow user agents to transmit RST_STREAM upon seeing a redirect · whatwg/fetch@af0dc92 ( 版) https://github.com/whatwg/fetch/commit/af0dc923f7636751996a9762309904511725a1a7
[72] Non-HTTP(S) schemes are a network error during redirects ( (annevk著, )) https://github.com/whatwg/fetch/commit/9b75908a1e6f6f520a77b8b420015a61fb5d8512
[73] Navigate: remove "gone async" and define redirect handling (annevk著, ) https://github.com/whatwg/html/commit/8b630f5e4fa2ec8b0999470d09490bffe6e9a1e3
[75] Call out to Referrer Policy to set policy on redirect (estark37著, ) https://github.com/whatwg/fetch/commit/a8f1cd5ae2d080ee4e1e8e02b68e8ec6ae2c2833
Ensured the redirection count is no more than 20 in case of cross origin requests (r208046)
Ensured redirections are upgraded only if declared by CSP policy (r207752)
Receivers should place limits on the number of HTTP redirects they follow, for example limiting the number to 20, in order to prevent being stuck in a redirect loop if the sender continues to send redirects.
[80] Do not always set the recursive flag in HTTP-redirect fetch (annevk著, ) https://github.com/whatwg/fetch/commit/869ec2c2224200988bbc604f7f5181b6bb9df2c3
[81] RFC 5323 - Web Distributed Authoring and Versioning (WebDAV) SEARCH () https://tools.ietf.org/html/rfc5323#section-5.4
[82] More eargerly send RST_STREAM on redirects (annevk著, ) https://github.com/whatwg/fetch/commit/fd286755e9664d570260c16f7c1933f424d2f39a
[83] Clarify semantics of checking done, closed, etc. states of a null body stream · Issue #635 · whatwg/fetch () https://github.com/whatwg/fetch/issues/635
[84] More eargerly send RST_STREAM on redirects by annevk · Pull Request #638 · whatwg/fetch () https://github.com/whatwg/fetch/pull/638
ads.txt v1.0.1 への仕様更新に伴い、Google では元のルートドメイン外への単一の HTTP リダイレクトがサポートされるようになります(例: example1.com/ads.txt から example2.com/ads.txt へのリダイレクト)。
元のルートドメイン内であれば、複数のリダイレクトもサポートされます。
[86] Response.redirect() results in status message still being OK? · Issue #664 · whatwg/fetch () https://github.com/whatwg/fetch/issues/664
[87] "no-cors" POST and 307/308 redirects · Issue #593 · whatwg/fetch () https://github.com/whatwg/fetch/issues/593
[88] Avoid using the CORS flag to reset request's origin in redirects by annevk · Pull Request #594 · whatwg/fetch () https://github.com/whatwg/fetch/pull/594
[89] Preserve HEAD method on 303 redirect (annevk著, ) https://github.com/whatwg/fetch/commit/6f29b764cc57aaf2f431e15a3f0fec029926e9e0
[90] 303 redirects should preserve HEAD · Issue #753 · whatwg/fetch () https://github.com/whatwg/fetch/issues/753
[91] Preserve HEAD method on 303 redirect by annevk · Pull Request #796 · whatwg/fetch () https://github.com/whatwg/fetch/pull/796
[92] Added a note about fetch redirects being covered by andypaicu · Pull Request #359 · w3c/webappsec-csp () https://github.com/w3c/webappsec-csp/pull/359
[93] Note somewhere that redirects are covered by fetch directives. · Issue #72 · w3c/webappsec-csp () https://github.com/w3c/webappsec-csp/issues/72
[94] Take tainted origin flag into account for the same origin check (annevk著, ) https://github.com/whatwg/fetch/commit/986618a62b2d7d31f93177ed178f0cb21b570d85
[95] fetch() "no-cors": cross-origin to same-origin redirect taints response · Issue #737 · whatwg/fetch () https://github.com/whatwg/fetch/issues/737
[96] Request's tainted origin flag fallout · Issue #756 · whatwg/fetch () https://github.com/whatwg/fetch/issues/756
[97] Take tainted origin flag into account for the same origin check by annevk · Pull Request #834 · whatwg/fetch () https://github.com/whatwg/fetch/pull/834
[101] RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources, , https://www.rfc-editor.org/rfc/rfc4437.html
301
,302
,303
,307
,308
の5種類だけです。