web-dev-qa-db-ja.com

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

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

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

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

  1. 元のURLにフラグメント(/original.php#foo)があり、/new.phpへのリダイレクトが行われた場合、元のURLのフラグメント部分は単純に失われますか?または、新しいURLに時々適用されますか?
    この場合、新しいURLは/new.php#fooになりますか?

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

129
levik

2014年6月27日更新

RFC 7231、ハイパーテキスト転送プロトコル(HTTP/1.1):セマンティクスとコンテンツ は、提案された標準として公開されています。 Changelog から:

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

セクション7.1.2。場所 からの重要なポイント:

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

たとえば、URI参照「 http://www.example.org/~tim 」に対して生成されたGET要求は、ヘッダーフィールドを含む303(See Other)応答になります。

Location: /People.html#tim

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

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

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のフラグメント識別子とリダイレクトを結合する必要がある場合の動作は未定義です。現在のユーザーエージェントは実際、どのフラグメントが優先されるかによって異なります。」

[...]

IE8doesLocationからのフラグメントidenfitierを使用するようです(私が見た動作はlocalhostに制限されるかもしれません)。

したがって、Safari/IE/Firefox/Chrome(テスト済み)の動作は一貫しており、元のURIが何であってもLocationヘッダーのフラグメントが使用されているようです。

そのため、私は提案を変更して、期待される動作としてthatを文書化します。

これにより、ほとんどのブラウザと互換性があり、将来の証拠になります(この問題は最終的に標準化されるため)質問への回答:

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

B:Locationヘッダーからのフラグメントが尊重されます。

127
ax.

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 をご覧ください。 =

40
EricLaw

お知らせするために、ここで適切な仕様を見つけることができます。すべての動作を定義する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

9
Marcin