带有代码 3xx 和空“位置”标头的 HTTP 响应

Posted

技术标签:

【中文标题】带有代码 3xx 和空“位置”标头的 HTTP 响应【英文标题】:HTTP responses with code 3xx and empty 'Location' header 【发布时间】:2014-02-14 04:58:50 【问题描述】:

我正在使用 Java (HttpURLConnection) 连接到 URL。

我注意到在某些情况下,响应代码是 3xx 但“位置”标头为空。

客户端浏览器收到这种HTTP响应后如何知道重定向到哪里?

谢谢

【问题讨论】:

【参考方案1】:

并非所有3xx 回复都可以自动重定向。

300 在响应正文中提供多个 URL,而不是在 Location 标头中。客户/用户必须决定接下来要检索哪一个。

301302303307 仅在下一个 URL 已知时才提供 Location。否则,客户/用户必须决定下一步该做什么。

304 不是重定向。它是对条件 GET 的响应,其中请求的内容自上次满足请求的条件以来没有更改。

305 始终为需要连接的代理提供Location

306 不再使用。

【讨论】:

这并不能完全回答问题。空的 Location 标头可能被视为有效重定向到最初请求的同一 URI。此外,如果服务器有首选选项,300 响应应该在响应正文中的 URL 之外提供 Location 标头。此外,如果没有 Location 标头,301302303307308 就没有任何意义。【参考方案2】:

如果您查看某些 3xx 状态代码上的 HTTP spec,其中一些仅应该提供 Location 标头。

客户端浏览器收到此信息后如何知道重定向到哪里 什么样的 HTTP 响应?

它没有。在这种情况下,由客户负责处理。

【讨论】:

那么您能解释一下浏览器最终是如何“到达”某个地方的吗?它是否从 javascript 获取最终 URL? @barakmanos 取决于浏览器。查看this bugzilla 问题。【参考方案3】:

位置标头在与3xx 重定向状态代码一起使用时重定向用户代理以检索另一个URI 引用,304 Not Modified 除外。可以提供绝对 URI 和相对引用,包括引用当前资源的空引用(有关详细信息,请参阅URI specification)。

不过,只有 Firefox 和旧版 Edge 接受空的 Location 标头;新的 Edge 和 Chrome 没有。尽管 HTTP 重定向仅用于重定向到不同的资源或 URI(请参阅RFC 7231 section 6.4),但所有浏览器都实现了显式引用同一页面的非空 Location 标头。

每当用户代理收到重定向状态代码但没有 Location 标头(或无效的 Location 标头或在 Chrome 的情况下为空的 Location 标头)时,它不会重定向但显示响应正文。这也适用于用户禁用自动重定向时。因此,响应正文还应包含相应的链接。

Empty Location 标头显然会引入重定向循环。尽管如此,状态码 303 See Other 可以与空的 Location 标头一起使用,以使用相同的 URI 实现 Post/Redirect/Get 习惯用法。此习惯用法可防止用户在重新加载页面时使用 POST 重新提交相同的表单,因为303 See Other 要求用户代理在关注新位置时使用 GET 请求方法。 301 Moved Permanently302 Found 也可能将请求方法更改为 GET(但也可能不会); 307 Temporary Redirect308 Permanent Redirect 永远不会改变请求方法。

虽然这个用例看起来有点优雅,但我不建议实施它,因为浏览器支持不同。

【讨论】:

以上是关于带有代码 3xx 和空“位置”标头的 HTTP 响应的主要内容,如果未能解决你的问题,请参考以下文章

使用 java servlet 在重定向响应中丢失 HTTP 自定义标头

发送带有 http 标头的 curl 请求

是否可以在标头中添加错误处理程序(“位置:”.$_SERVER[“HTTP_REFERER”]);在php中

带有授权标头的离子 http 请求

在 AWS Cloudfront 源请求中返回带有 set-cookie 标头的响应

从 Chrome 重定向到带有位置标头的 302 后被阻止的 Android 应用