【问题标题】:URL Fragment and 302 redirectsURL 片段和 302 重定向
【发布时间】:2011-01-18 04:30:58
【问题描述】:

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

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

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

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

  2. 无论原始 URL 是什么,如果服务器重定向到带有片段 (/new.php#foo) 的新 URL,该片段会得到“尊重”吗?或者服务器真的没有业务干扰片段 - 因此浏览器是否会通过简单地转到 /new.php 来忽略它??

【问题讨论】:

标签: redirect fragment-identifier http-redirect


【解决方案1】:

张贴类似的issue with the solution 面对我。

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

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

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

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

由于 redirect 隐藏变量 value 仅包含 /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 将其重定向到 IE 中的/myapp/#/pending/requests

上述解决方案在所有三个浏览器Chrome, Firefox and IE 中都能正常工作。

感谢@AlexFord 对此问题的detailed explanation and providing solution

【讨论】:

    【解决方案2】:

    只是让您知道,在这里您可以找到合适的规格。通过 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(一个 URI 的特殊情况)通过 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.

    【讨论】:

      【解决方案3】:

      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 的片段组件 用于生成请求目标的引用(即重定向 继承原始引用的片段(如果有)。

      例如,一个 为 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”,保留原文 片段标识符。

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

      更新结束

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

      #6 允许 Location 标头中的片段。 #43 这么说:

      我刚刚用各种浏览器测试了这个。

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

      建议:

      "注意:当来自原始 URI 的片段标识符和重定向需要组合时的行为是未定义的;当前的用户代理在哪个片段优先方面确实存在差异。"

      [...]

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

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

      因此,我更改了我的建议,以记录 符合预期的行为。

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

      答:来自原始 URL 的片段会被丢弃。

      B: 来自 Location 标头的片段被接受。

      【讨论】:

      • 我忘记了我在 HTTP 服务器中设置的一些“重写”规则,这些规则可能是作为 301 重定向实现的。结果 IE 不断丢失片段标识符,因为当您有多个重定向时,第一个重定向设置的片段成为第二个 source URI 的一部分。
      • opera 12.12 尊重位置标头中存在的片段。
      • 在 Chrome 和 Firefox 的当前版本上:A 不正确。在当前版本的 Firefox 上:B 不正确。目前,如果您必须使用哈希(例如,使用 Backbone 的路由),似乎基于 javascript 的重定向是您唯一真正的选择。
      • 引用的块似乎自相矛盾。首先它说“IE (8) 忽略位置 URI 中的片段,因此将使用源 URI 中的片段,如果存在”,然后它说“看起来 IE8 确实使用了来自位置的片段标识符”。第一个是指与第二个不同的东西吗?
      • B 不适用于 Chome 45.0.2454.85。 B 适用于 Firefox 40.0.3。
      【解决方案4】:

      如果发生 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查看有关此问题的进一步讨论

      【讨论】:

      • 实际上 IE10 的行为仍然与最新的 Firefox 和 Chrome 版本不同。在简单重定向的情况下,它似乎确实保留了源 URL 中的片段。如果重定向Location 包含一个片段,它将正确保存它。 但是如果带有片段的重定向Location经过另一个3xx重定向,它会莫名其妙地忽略第一次重定向的片段,这与之前的2个行为不一致。 Chrome 和 Firefox 始终保留它。
      • 我已经确认你是正确的。见本页最终测试链接:webdbg.com/test/redir/fragment
      猜你喜欢
      • 2020-11-05
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 2017-05-29
      • 2014-12-18
      • 2019-08-02
      • 1970-01-01
      相关资源
      最近更新 更多