URL片段和302重定向


136

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

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

我的问题确实有两点:

  1. 如果原始URL带有一个片段(/original.php#foo),并且重定向到/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

Answers:


135

更新2014年6月27日

RFC 7231,超文本传输​​协议(HTTP / 1.1):语义和内容,已发布为拟议标准。从变更日志

更改了位置标头字段的语法,以允许所有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 ”,并保留原始片段标识符。

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

更新完

这是当前HTTP规范的未解决(未指定)问题。IETF httpbis工作组的两个问题对此进行了处理

#6允许Location标头中包含片段。#43说:

我刚刚使用各种浏览器进行了测试。

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

提案:

“注意:当需要合并来自原始URI和重定向的片段标识符时的行为是不确定的;当前的用户代理确实在哪个片段优先上有所不同。”

[...]

看来IE8 确实使用了片段idenfitier Location(我看到的行为可能仅限于本地主机)。

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

因此,我改变我的建议文件为预期的行为。

这将导致与浏览器的兼容性最佳,并且可以用于将来的验证(因为此问题最终将被标准化)回答您的问题:

答:原始网址的片段会被丢弃。

B:Location标头中的片段受到尊重。


1
我忘记了在HTTP服务器中设置的一些“重写”规则,这些规则可能实现为301重定向。结果,IE一直丢失片段标识符,因为当您有多个重定向时,由第一个重定向设置的片段将成为第二个重定向的 URI的一部分。
Eugene Yokota

Opera 12.12会尊重位置标头中的片段(如果存在)。
山羊

4
在Chrome和Firefox的当前版本上:A不是正确的。在当前版本的Firefox中:B不是正确的。目前,如果您必须使用哈希(例如,使用Backbone的路由),那么基于javascript的重定向似乎是您唯一的选择。
13年

引用的块似乎自相矛盾。首先说“ IE(8)忽略位置URI中的片段,因此将使用源URI中的片段(如果存在)”,然后说“看来IE8确实使用了位置中的片段标识符”。第一个是指与第二个有所不同吗?
davidtbernal 2014年

对于Chome 45.0.2454.85,B不是正确的。B对于Firefox 40.0.3是正确的。
姚敬国

44

如果发生HTTP / 3xx重定向,则Safari 5和IE9及以下版本将删除原始URI的片段。如果响应上的Location标头指定一个片段,则使用该片段。

遵循3xx重定向后,IE10 +,Chrome 11 +,Firefox 4+和Opera都将“重新附加”原始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

我确认您是正确的。请参阅此页面上的最终测试链接:webdbg.com/test/redir/fragment
EricLaw 2013年

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]中详细描述了所需的行为。术语“永久统一资源定位符(PURL)”表示一个URL(URI的一种特殊情况),该URL通过HTTP重定向指向另一个。有关更多信息,请参阅“持久统一资源定位符” [PURL]。例:

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


0

发布与我面临的解决方案类似的问题

希望它对具有preserving hash in IE302重定向的类似要求的人有所帮助。

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

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

我想通了,认证成功后,SiteMinder正在做302 redirection使用用户请求的应用程序页面的登录表单隐变量value(它存储用户请求的URL /myapp/- without hash fragment因为它不会被发送到服务器)与类似的名称redirect。下面的样本表格

样本登录表格

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

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

已经浪费了将近一天的时间来弄清楚这种行为。

解决方案是:

通过添加现有值来更改登录表单隐藏变量(redirect)的以保存哈希片段window.location.hash。类似于下面的代码

$(function () {
  var $redirect = $('input[name="redirect"]');
  $redirect.val($redirect.val() + window.location.hash);
});

进行此更改后,redirect隐藏变量将用户请求的URL值存储为/myapp/#/pending/requestsSiteMinder并将其重定向到/myapp/#/pending/requestsIE中。

上面的解决方案在所有三种浏览器中都可以正常工作Chrome, Firefox and IE

感谢@AlexFord提供详细说明并提供此问题的解决方案

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.