URLフラグメントと302リダイレクト


136

URLフラグメント(の後の部分#)がサーバーに送信されないことはよく知られています。

サーバーのリダイレクト(HTTPステータス302およびLocation:ヘッダー経由)が関係している場合、フラグメントはどのように機能するのでしょうか。

私の質問は本当に2つあります。

  1. 元のURLにフラグメント(/original.php#foo)があり、にリダイレクトされた場合、元のURL /new.phpのフラグメント部分は単に失われるだけですか?それとも、新しいURLに適用されることがありますか?この場合
    、新しいURLは存在します/new.php#fooか?

  2. 元のURLに関係なく、サーバーがフラグメント(/new.php#foo)を使用して新しいURLにリダイレクトした場合、フラグメントは「称賛」されますか?または、サーバーは実際にはフラグメントに干渉するビジネスをまったく持っていません-したがって、ブラウザは単に移動するだけでフラグメントを無視します/new.phpか?


1
ここにW3Cによる仕様があります:w3.org/TR/cuap#uri条項4.1。フラグメントはリダイレクト時に保持する必要があります。
Marcin

回答:


135

2014年6月27日更新

RFC 7231、Hypertext Transfer Protocol(HTTP / 1.1):Semantics and Contentは、PROPOSED STANDARDとして公開されています。変更ログから:

Locationヘッダーフィールドの構文が変更され、相対参照やフラグメントを含むすべてのURI参照が許可されるようになり、フラグメントの使用が適切でない場合の明確化も行われました。(セクション7.1.2)

7.1.2項の重要なポイント場所

3xx(リダイレクト)応答で提供されるLocation値にフラグメントコンポーネントがない場合、ユーザーエージェントは、値がリクエストターゲットの生成に使用されるURI参照のフラグメントコンポーネントを継承するかのようにリダイレクトを処理する必要があります(つまり、リダイレクトは継承します)元の参照のフラグメント(存在する場合))。

たとえば、URI参照 " http://www.example.org/~tim " に対して生成されたGETリクエストは、ヘッダーフィールドを含む303(その他を参照)レスポンスになる可能性があります。

Location: /People.html#tim

これは、ユーザーエージェントが「http://www.example.org/People.html#tim」にリダイレクトすることを示唆しています

同様に、URI参照「http://www.example.org/index.html#larry」に対して生成されたGETリクエストは、ヘッダーフィールドを含む301(永久に移動)応答になる可能性があります。

Location: http://www.example.net/index.html

これは、ユーザーエージェントが「http://www.example.net/index.html#larry」にリダイレクトし、元のフラグメント識別子を保持することを示唆しています。

これはあなたの質問に明確に答えるはずです。

ENDを更新

これは、現在のHTTP仕様でのオープンな(指定されていない)問題です。IETF httpbisワーキンググループの 2つの問題で対処されています。

#6はLocationヘッダーのフラグメントを許可します。#43はこれを言います:

これをさまざまなブラウザでテストしました。

  • FirefoxとSafariは、ロケーションヘッダーでフラグメントを使用します。
  • Operaは、存在する場合、ソースURIからのフラグメントを使用します。それ以外の場合、リダイレクト場所からのフラグメントを使用します
  • IE(8)はロケーションURIのフラグメントを無視するため、存在する場合はソースURIのフラグメントを使用します

提案:

「注:元のURIからのフラグメント識別子とリダイレクトを組み合わせる必要がある場合の動作は定義されていません。現在のユーザーエージェントは、実際に優先されるフラグメントが異なります。」

[...]

IE8 idenfitierのフラグメントを使用しているようですLocation(私が見た動作はlocalhostに制限されている可能性があります)。

したがって、元のURIが何であっても、Locationヘッダーのフラグメントが使用されるという点で、Safari / IE / Firefox / Chromeで一貫した動作をしているように見えます。

したがって、私は提案を変更して、それを予想どおりの動作として文書化ます。

これにより、ブラウザの互換性が最も高くなり、将来的には証明されます(この問題は最終的に標準化されるため)。

A:元のURLのフラグメントは破棄されます。

B:Locationヘッダーのフラグメントが受け入れられます。


1
おそらく301リダイレクトとして実装された、HTTPサーバーで設定した「書き換え」ルールの一部を忘れていました。結果として、複数のリダイレクトがある場合、最初のリダイレクトによって設定されたフラグメントが2番目のソース URIの一部になるため、IEはフラグメント識別子を失い続けました。
Eugene Yokota

opera 12.12は、存在する場合、locationヘッダーのフラグメントを尊重します。
ヤギ

4
ChromeとFirefoxの両方の現在のバージョン:Aは正しくありません。Firefoxの現在のバージョン:Bは正しくありません。現時点では、ハッシュを使用する必要がある場合(たとえば、バックボーンのルーティングを使用する場合)、JavaScriptベースのリダイレクトが唯一の現実的なオプションのようです。
a.real.human.being 2013年

引用されたブロックはそれ自体と矛盾しているようです。最初に「IE(8)はロケーションURIのフラグメントを無視するため、存在する場合はソースURIからのフラグメントを使用します」と表示し、次に「IE8はロケーションからのフラグメント識別子を使用しているように見える」と表示します。最初のものは2番目のものとは別のものを指しているのですか?
davidtbernal 2014年

BはChome 45.0.2454.85には当てはまりません。BはFirefox 40.0.3に当てはまります。
Jingguo Yao

44

Safari 5およびIE9以下では、HTTP / 3xxリダイレクトが発生すると、元のURIのフラグメントがドロップされます。応答のLocationヘッダーがフラグメントを指定している場合は、それが使用されます。

IE10 +、Chrome 11 +、Firefox 4 +、Operaはすべて、3xxリダイレクト後に元のURIのフラグメントを「再接続」します。

テストページ:http : //www.webdbg.com/test/redir/fragment/

この問題の詳細については、http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspxを参照してください。


2
実際、IE10の動作は、最新のFirefoxおよびChromeバージョンとは異なります。単純なリダイレクトの場合、ソースURLからのフラグメントを保持しているようです。リダイレクトLocationにフラグメントが含まれている場合は、正しく保持されます。しかしLocation、フラグメントでリダイレクトされたものが別の3xxリダイレクトを通過する場合、最初のリダイレクトからのフラグメントを不可解に無視します。これは、以前の2つの動作と一致しません。ChromeとFirefoxは一貫してそれを保持します。
odony 2013年

あなたが正しいことを確認しました。このページの最後のテストリンクを参照してください:webdbg.com/test/redir/fragment
EricLaw

11

ただお知らせするために、ここで適切な仕様を見つけることができます。すべてがどのように動作するかを定義するw3cによる:http : //www.w3.org/TR/cuap#uri-条項4.1- 以下を参照:

リソース(URI1)が移動したとき、HTTPリダイレクトは新しい場所(URI2)を示すことができます。

URI1にフラグメント識別子#fragがある場合、ユーザーエージェントが到達しようとしている新しいターゲットはURI2#fragになります。URI2に既にフラグメント識別子がある場合、#fragを追加してはならず、新しいターゲットはURI2です。

誤り:現在のユーザーエージェントのほとんどはHTTPリダイレクトを実装していますが、フラグメント識別子を新しいURIに追加していません。これにより、ユーザーが誤ったリソースで終了するため、ユーザーを混乱させます。

参照:

HTTPリダイレクトについては、HTTP / 1.1仕様[RFC2616]のセクション10.3で説明されています。必要な動作については、「リダイレクトされたURLのフラグメント識別子の処理」[RURL]で詳しく説明されています。「Persistent Uniform Resource Locator(PURL)」という用語は、HTTPリダイレクトを介して別のURLを指すURL(URIの特殊なケース)を示します。詳細については、「Persistent Uniform Resource Locators」[PURL]を参照してください。例:

ユーザーがhttp://www.w3.org/TR/WD-ruby/#changesでリソースをリクエストし 、サーバーがユーザーエージェントをhttp://www.w3.org/TR/ruby/にリダイレクトするとします。後者のURIを取得する前に、ブラウザはフラグメント識別子#changesを追加する必要があります:http : //www.w3.org/TR/ruby/#changes


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.