URL片段和302重定向

时间:2010-02-18 04:55:29

标签: redirect fragment-identifier http-redirect

众所周知,URL片段(#之后的部分)未发送到服务器。

我确实想知道当涉及服务器重定向(通过HTTP状态302和Location:标头)时片段如何工作。

我的问题实际上是双重的:

  1. 如果原始网址包含片段(/original.php#foo),并且重定向到/new.php,原始网址的片段部分是否会丢失?或者它有时会应用到新的URL?
    在这种情况下,新网址是/new.php#foo吗?

  2. 无论原始网址如何,如果服务器重定向到带有片段(/new.php#foo)的新网址,该片段是否会被“尊重”?或者服务器真的没有任何业务干扰片段 - 因此浏览器会忽略它,只需转到/new.php ??

4 个答案:

答案 0 :(得分:126)

更新2014年6月 - 27日

RFC 7231, Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content已作为建议标准发布。来自Changelog

  

Location头字段的语法已更改为允许所有   URI引用,包括相对引用和片段   关于何时使用碎片的一些说明   适当。 (第7.1.2节)

Section 7.1.2. Location的重点:

  

如果3xx(重定向)响应中提供的位置值有效   没有片段组件,用户代理必须处理   重定向,好像该值继承了URI的片段组件   用于生成请求目标的引用(即重定向)   继承原始引用的片段(如果有的话)。

     

例如,a   为URI引用生成GET请求   “http://www.example.org/~tim”可能会导致303(见其他)   包含标题字段的响应:

Location: /People.html#tim
     

表示用户代理重定向到   “http://www.example.org/People.html#tim

     

同样,为URI引用生成了GET请求   “http://www.example.org/index.html#larry”可能会导致301(移动   包含标题字段的永久响应:

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

表示用户代理重定向到   “http://www.example.net/index.html#larry”,保留原文   片段标识符。

这应该清楚地回答你的问题。

更新END

这是current HTTP specification的开放(未指定)问题。它在IETF httpbis working group的两个问题中得到解决:

#6允许Location标题中的片段。 #43说:

  

我刚用各种浏览器测试过它。

     
      
  • Firefox和Safari使用位置标题中的片段。
  •   
  • Opera使用源URI中的片段(如果存在),否则使用重定向位置的片段
  •   
  • IE(8)忽略位置URI中的片段,因此将使用源URI中的片段(如果存在)
  •   
     

提案:

     

“注意:原始URI中的片段标识符和重定向需要组合时的行为是未定义的;当前用户代理确实在哪个片段优先。”

     

[...]

     

似乎IE8 使用来自Location的片段idenfitier(我看到的行为可能仅限于localhost)。

     

因此,我们似乎对Safari / IE / Firefox / Chrome(刚刚测试过)有一致的行为,因为无论原始URI是什么,都会使用Location头中的片段。

     

因此,我将我的提案更改为将 记录为预期的行为。

这导致了大多数浏览器兼容和未来的证明(因为这个问题最终会标准化)回答你的问题:

来自原始网址的

A:片段会被丢弃。

B:来自Location标题的片段受到尊重。

答案 1 :(得分:39)

如果发生HTTP / 3xx重定向,则Safari 5和IE9及以下版本会丢弃原始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 :(得分:9)

只是为了让您知道,在这里您可以找到合适的规格。通过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的第10.3节中描述   规范[RFC2616]。详细描述了所需的行为   在“处理重定向URL中的片段标识符”[RURL]中。该   术语“持久统一资源定位符(PURL)”表示URL(a   URI的特殊情况,通过HTTP指向另一个URI   重定向。有关更多信息,请参阅“持久统一资源”   定位器“[PURL]。例如:

     

假设用户请求资源   http://www.w3.org/TR/WD-ruby/#changes并且服务器重定向   用户代理http://www.w3.org/TR/ruby/。在获取后者之前   URI,浏览器应该将片段标识符#changes附加到它:   http://www.w3.org/TR/ruby/#changes

答案 3 :(得分:0)

发布类似的issue with the solution我面临的情况。

希望对preserving hash in IE具有类似要求的302重定向用户有所帮助。

添加答案的必要部分,而不是单独添加链接

我们在应用程序中使用SiteMinder身份验证。

我发现,成功进行身份验证后,SiteMinder通过使用登录表单隐藏变量302 redirection (在其中存储用户value)对用户请求的应用程序页进行/myapp/用户请求的网址without hash fragment-redirect,因为它不会被发送到服务器),其名称类似于redirect。下面的示例表格

Sample login form

由于/myapp/隐藏变量 value 仅包含/myapp/,没有哈希片段,并且是302重定向,因此即使在进入我们的应用程序之前,IE也会自动删除哈希片段,并且无论我们在应用程序代码中尝试的解决方案如何,都无法解决。

IE仅重定向到https://ourapp.com/myapp/#/home,并且正在我们的应用redirect的默认主页上登陆。

浪费了几乎一天的时间来弄清这种行为。

解决方案是:

已更改登录表单隐藏变量(window.location.hash,以保留哈希片段 将$(function () { var $redirect = $('input[name="redirect"]'); $redirect.val($redirect.val() + window.location.hash); }); 与现有值一起附加。类似于以下代码

redirect

更改之后,/myapp/#/pending/requests隐藏变量将用户请求的URL值存储为SiteMinder,而/myapp/#/pending/requests将其重定向到IE中的Chrome, Firefox and IE

上述解决方案在所有三个浏览器 color_scale_rule = ColorScaleRule(start_type="percentile", start_value=0, start_color=colors.RED, mid_type="percentile", mid_value=50, mid_color=colors.YELLOW, end_type="percentile", end_value=100, end_color=colors.GREEN) 中都可以正常工作。

感谢@AlexFord解决了此问题,detailed explanation and providing solution