【问题标题】:What is the correct behavior expected of an HTTP POST => 302 redirect to GET?HTTP POST => 302 重定向到 GET 的正确行为是什么?
【发布时间】:2013-07-10 11:09:34
【问题描述】:

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

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

The HTTP spec says

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

提琴手正在显示:

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

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

  1. 规范中的某些内容使本节无关紧要
  2. 我对自动重定向的理解是错误的(执行 GET 的 chrome 浏览器并没有真正自动重定向)
  3. 作为用户,我的理解确认了这一点
  4. 还有别的吗?

【问题讨论】:

    标签: http redirect http-status-codes


    【解决方案1】:

    规范中的下一行开始:

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

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


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

    【讨论】:

    • abarnet:请澄清您所说的“旧浏览器”是什么意思。
    • @JulianReschke:我不太清楚。如果我不得不猜测,我猜这个年份大约是 IE6 和 FF 1.9。但请记住,桌面浏览器(和 WebKit 移动浏览器)并不是唯一的用户代理。有很多人在使用其他设备,其中包含浏览器、手动编码的 Web 服务客户端或抓取工具等。
    • @JulianReschke:另外,我应该提到 303 和 307 仅在 HTTP/1.1 中。有很多服务器和缓存(以及一些用户代理)要么无法处理 1.1,要么禁用它。与此同时,我刚刚从 IE 团队找到了看起来相关的blog post
    • FF 1.9 似乎与我无关。 IE6确实支持307。到最后,你总会发现一些客户端坏了,所以你需要画一条线。
    • @JulianReschke:我并不是说你的服务器应该滥用 302,我是在解释为什么许多服务器仍然这样做。只要所有新浏览器都能正确处理损坏的行为(并且确实如此),并且有任何旧浏览器需要损坏的行为,服务器就会继续滥用它。这不是一件好事,但这是事实。
    【解决方案2】:

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

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

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

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

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

    另外我得到了

    请求的资源上没有“Access-Control-Allow-Origin”标头

    这是一个 CORS 问题。

    然而解决方案是使用 HTTPS 而不是 HTTP。

    然后你就会有

    请求:POST /formHandler -> 响应:200 Ok

    【讨论】:

      【解决方案3】:

      您可能想阅读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 进行方法重写;因此,当原始请求为 POST 时,此规范使该行为符合要求。

      【讨论】:

        猜你喜欢
        • 2016-09-15
        • 2021-10-29
        • 2016-01-17
        • 1970-01-01
        • 2023-03-21
        • 2018-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多