对于哪些3xx HTTP代码,Location头是必需的?

时间:2013-04-24 14:44:05

标签: http

RFC 2616Location标头定义为:

  

Location response-header字段用于将收件人重定向到Request-URI以外的位置,以完成请求或标识新资源
  ...
  对于3xx响应,位置应该应该指示服务器自动重定向到资源的首选URI。

AFAIK,对于3xx Redirection代码,Location标题为:

  • 300多种选择:可选
  • 301永久移动:必需
  • 302发现:必需
  • 303见其他:必需
  • 304 Not Modified:不相关
  • 305使用代理:无关(?)
  • 306 Switch Proxy:无关(?)
  • 307临时重定向:必需
  • 308永久重定向:必需

但这仅仅来自个人经历。是否有标准定义了哪些HTTP代码需要要发送Location标头?

也就是说,在没有相应的Location标题的情况下,HTTP客户端应该为3xx代码抛出异常?

1 个答案:

答案 0 :(得分:6)

这个问题已经在RFC 2616仍然是权威的时候被问到,所以现在看起来是一个有趣的研究项目,RFC 7230到7235已经到位。所以,让我们看看我们在这里得到了什么。

现在RFC 7231, section 7.1.2中定义了Location标头:

  

"位置" header字段在某些响应中用于引用与响应相关的特定资源。关系类型由请求方法和状态代码语义的组合定义。

     

[...]

     

对于201 (Created)响应,Location值指的是请求创建的主要资源。对于3xx(重定向)响应,Location值指的是自动重定向请求的首选目标资源。

该部分并不将此标题仅限于3xx范围的状态代码。事实上,明确提到的唯一状态代码是201(已创建)和303 (See Other)。但是,任何状态代码都没有关于此标题实际上是必需的信息。

现在,RFC 7231, section 6.4描述了3xx代码范围的目的:

  

3xx(重定向)类状态代码表示用户代理需要采取进一步的操作才能完成请求。 如果提供了Location头字段,则用户代理 MAY 会自动将其请求重定向到Location字段值引用的URI,即使不了解特定的状态代码也是如此。

措辞表明,无论是存在还是自动重定向到其内容都是强制性的。

在撰写本文时,IANA HTTP Status Code Registry列出了已注册的代码300到308。如果一个(305)被废弃而一个被保留(306),则剩下七个活动代码:

300:多种选择 - RFC 7231, section 6.4.1

如果服务器知道资源的多个表示,则返回300代码。从RFC 7231开始,不再使用推荐的方式来传达可能的表示列表,尽管提到了通过RFC 5988Link标题。关于Location标题,RFC可以这样说:

  

如果服务器有首选项,服务器应该生成一个Location头字段,其中包含首选项的URI引用。用户代理可以使用Location字段值进行自动重定向。

意味着只有在服务器具有首选表示时才使用Location标头。如果没有,服务器根本没有这样的偏好。

值得一提的是Location标题本身不适合列出所有可能的表示形式,因为它的语法是一个不能包含列表的单值字段。因此,

的含义
Location: //example.com/a
Location: //example.com/b

未定义。

301:永久移动 - RFC 7231, section 6.4.2

此响应代码是让客户端知道所请求资源有一个全新的位置:后续请求将定向到Location标头中指定的位置。

  

服务器应该在响应中生成一个Location头字段,其中包含新永久URI的首选URI引用。用户代理可以使用Location字段值进行自动重定向。

同样,Location标题的存在并非绝对必要。没有这个标题将具有可疑的实用性。语义与410 (Gone)响应类似 - 但不相等:"此资​​源已永久移至新的未知位置。"

302:找到 - RFC 7231, section 6.4.3

最初这已被指定为"临时重定向"并在以后的规格中重命名。与301相比,这个不能(或不应该)被缓存或用于永久重写URL。该规范的相关部分是:

  

服务器应该在响应中生成一个Location头字段,其中包含不同URI的URI引用。用户代理可以使用Location字段值进行自动重定向。

我认为缺少Location标题的语义与301几乎相同:"此资​​源已暂时移至新的未知位置。"

303:见其他 - RFC 7231, section 6.4.4

应该返回

303以响应POST请求,但适用于任何方法。一般来说,它意味着让客户知道在替代URL处有更合适的表示,或者所请求的资源不能通过HTTP传输。

在这个问题的背景下,这是一个头脑风暴。 RFC 2616, section 10.3.4州:

  

不同的URI应该由响应中的Location字段给出。

较新的RFC 7231的相关部分似乎只是假设存在Location标题:

  

服务器正在将用户代理重定向到其他资源,如Location头字段中的URI所示

在勘误中没有任何内容可以澄清这一点,所以我倾向于假设RFC 2616的位置。缺少Location标题的语义根据请求方法而有所不同:

304:未修改 - RFC 7232, section 4.1

这种反应在某种程度上是特殊的,因为它强调了[指示]用户代理需要采取进一步的行动才能完成请求。"应该理解为重定向不是新URI而是to a local cache。在RFC 7232的相关部分中根本没有提到Location标题。事实上,对于我的理解,这对于语义来说是没有意义的,因为这个实体的请求呈现仍然没有链接,你会在你的本地缓存中找到..."这很大程度上违背了关注点,但并不是说在这个地方不允许Location。尽管如此,Content-Location或带有Link部分的rel=self标题更合适。前者正在接受明确提及:

  

生成304响应的服务器必须生成以下任何一个头部字段,这些字段将在对同一请求的200 (OK)响应中发送:Cache-ControlContent-Location,{{3 }},DateETagExpires

305:使用代理 - Vary; RFC 2616, section 10.3.6

由于安全问题,此状态代码自RFC 7231起已被弃用(cf RFC 7231, section 6.4.5)。它在RFC 2616中的定义如下:

  

必须通过Location字段提供的代理访问所请求的资源。

暗示存在Location标头,但它并未明确要求它。省略此标题将具有&#34的语义含义;此资源只能通过某些代理访问。"

306:切换代理 - Appendix B

在RFC 2068最终确定并且已经被RFC 2616废弃之后,代码已作为草案引入。据我所知,该草案从未达到推荐的状态,因此这纯粹是为了完整性。该草案的基本原理是为代理提供一种机制,将客户(临时)引导到其他代理以便后续请求。

该草案的一部分是引入Set-Proxy标题,用于代替每draft-cohen-http-305-306-responses-00Location标题:

  

在最初的HTTP / 1.1规范中,'位置'标头用于指示代理设置。它的使用被“集合代理”和“#39;在305响应的上下文中的标头。所有新实现必须发送Set-proxy头。实施可以发送'位置'标题以便允许向后兼容。

然后

Set-Proxy在306的上下文中必需,而Location标头纯粹是可选的。由于所需的Set-Proxy机制旨在替换Location,因此后一个标头的缺失不会引入语义变化。

307:临时重定向 - section 2.2

由于HTTP / 1.1中302的语义更改导致307被引入:虽然通过302 重定向可以更改请求方法,但重定向的请求必须具有与原始请求相同的请求方法。

规范的相关部分是:

  

服务器应该在响应中生成一个Location头字段,其中包含不同URI的URI引用。用户代理可以使用Location字段值进行自动重定向。

同样,Location似乎是可选的。对于由于缺少标题而导致的语义更改,请参阅302。

308:永久重定向 - RFC 7231, section 6.4.7

与307类似,通过308重定向是为了保留其原始请求方法。可以说308是301,而307是302。

来自规范的RFC 7538

  

服务器应该在响应中生成一个Location头字段,其中包含新永久URI的首选URI引用。

所以,总而言之,我们遇到了这种情况:

  • 暗示:1(305)
  • 可选:1(306)
  • 不提及:1(304)
  • 应该:6(300; 301; 302; 303; 307; 308)

那"应该"应在section 3

的上下文中阅读
  

这个词,或形容词"推荐",意味着在特定情况下可能存在忽略特定项目的正当理由,但在选择不同的课程之前必须理解并仔细权衡全部含义。

这与" MUST"的绝对要求不同。或者"要求" (也在那个RFC中)。简而言之:没有3xx级代码,Location标头是强制性的。

应该注意,缺少Location标题的问题是RFC 2119。来自not a new one

  

301,302,303和307仅在下一个URL已知时才提供位置。否则,客户/用户必须决定下一步做什么

相关问题