23

POST => 302 重定向到 GET 的正确行为是什么?

在 chrome 中(可能是大多数浏览器),在我 POST (到希望我重定向的资源)并收到 302 重定向后,浏览器会自动在 302 位置发出 GET。这甚至是一个众所周知的模式。但是我阅读规范的方式似乎表明这不应该发生。

HTTP规范说

如果收到 302 状态代码以响应 GET 或 HEAD 以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件。

提琴手正在展示:

REQUEST 1: POST URLA
RESPONSE 1: 302 redirect to URLB
REQUEST 2: GET URLB

上面的部分似乎是说浏览器不应该发出 GET 请求?我错过了什么?

  1. 规范中较早的部分使本节无关紧要
  2. 我对自动重定向的理解是错误的(并且执行 GET 的 chrome 浏览器并没有真正自动重定向)
  3. 我的理解作为用户确认了这一点
  4. 还有什么?
4

3 回答 3

26

规范中的下一行开始:

注意:RFC 1945 和 RFC 2068 指定不允许客户端更改重定向请求的方法。然而,大多数现有的用户代理实现将 302 视为 303 响应,无论原始请求方法如何,都对 Location 字段值执行 GET。状态码 303 和 307 已被添加用于希望明确明确期望客户端做出何种反应的服务器。

紧接着,它解释了应该如何处理 303,这正是您所看到的。


如果你问为什么服务器仍然使用 302 而不是 307,所有当前的浏览器都能正确处理,那是因为旧的浏览器不会处理它。如果您想知道为什么浏览器将 302 处理为 303,那是因为旧服务器期望它。确实没有办法摆脱这个循环,对于 HTTP 来说,将 302 恢复为它以前的意思可能会更好,并弃用它(对于非 GET/HEAD)以支持 307。

于 2013-07-12T01:11:37.763 回答
1

您可能想阅读http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-22.html#rfc.section.6.4.p.3,它试图澄清情况。

注意:在 HTTP/1.0 中,状态码 301(永久移动)和 302(找到)是为第一种重定向类型定义的([RFC1945],第 9.3 节)。早期的用户代理在应用到重定向目标的方法是与原始请求相同还是重写为 GET 方面存在分歧。虽然 HTTP 最初为 301 和 302 定义了前者的语义(以匹配其在 CERN 的原始实现),并定义了 303(参见其他)以匹配后者的语义,但流行的实践逐渐收敛于 301 和 302 的后者语义。HTTP/1.1 的第一个修订版添加了 307(临时重定向)来指示以前的语义,而不受不同实践的影响。10 多年后,大多数用户代理仍然为 301 和 302 进行方法重写;所以,

于 2013-07-12T06:05:46.170 回答
1

阿巴纳特是对的!我在使用 Google App Engine 时遇到了同样的问题,但我找到了不同的解决方案。

我对 appengine 的问题是,我在后端向 GO formHandler 发送了一个 POST 表单。但它执行如下。

请求 1:GET /formHandler -> 响应 1:找到 302

请求 1:POST /formHandler -> 响应 1:找到 302

请求 1:GET /formHandler -> 响应 1:200 好的。

另外我得到了

请求的资源上不存在“Access-Control-Allow-Origin”标头

这是一个CORS问题。

然而,最终的解决方案是使用 HTTP S而不是 HTTP。

然后你会有

请求:POST /formHandler -> 响应:200 确定

于 2016-12-21T10:03:01.607 回答