题 POST后,我应该进行302还是303重定向?


Web应用程序的常见方案是在修改数据库的POST后重定向。就像在用户创建数据库对象后重定向到新创建的数据库对象一样。

似乎大多数Web应用程序使用302重定向,但如果您希望使用GET获取重定向中指定的URL,则303根据规范似乎是正确的做法。从技术上讲,使用302,浏览器应该使用与获取原始URL相同的方法获取指定的URL,这将是POST。但大多数浏览器并不这样做。

302 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3

303 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4

我应该使用302还是303?


46
2018-02-26 19:01


起源


有关: HTTP重定向代码之间的差异, HTTP:POST请求收到302,如果重定向请求是GET吗? - Piotr Dobrogost
正如@porneL所指出的那样,RFC 2616的历史可以追溯到1999年,现在正式进入死据IETF HTTP工作组主席称(由RFC 7230至7235取代)。 - ChrisV


答案:


依靠。
在HTTP1.1中添加了303和307响应。
因此,严格遵守HTTP1.1 RFC的客户端代理应该可以使用303响应。
但是可能存在不完全符合或符合HTTP1.0并且无法处理303的代理。
因此,为了确保大多数客户端实现可以优雅地处理应用程序的响应,我认为302是最安全的选择。
摘录自 RFC-2616

注意:许多pre-HTTP / 1.1用户代理   不明白303         状态。当与这些客户端的互操作性成为一个问题时,         因为大多数用户代理会做出反应,所以可以使用302状态代码         如此处针对303描述的302响应。


16
2018-02-26 19:13



请记住,这个建议是从1999年开始的。 - Kornel
是的,但我仍然经常发现(通常是公司的)代理不完全符合1.1。我也谨慎对待。 - Mikaveli
@Mikaveli代理不执行重定向,因此这是无关紧要的。它只对UA很重要,如果你支持NN4 / IE4,那么303状态是你问题中最少的:) - Kornel
@porneL - 许多公司代理 做 缓存响应代码等 - 尤其是暂时/永久移动的事情。 - Mikaveli
@Mikaveli在最坏的情况下只是将响应标记为不可缓存?我真的怀疑人们会容忍一个如此破碎的代理人。缓存临时重定向会破坏许多网站(可能在登录之前/之后有重定向的任何内容)。 - Kornel


正确的是303。

我使用它并且没有发现任何与Netscape 4(1998年发布的)更新的UAs的兼容性问题 17年前)。

如果您使用302,那么您将面临UA将POST重新发送到新URL而不是切换到GET的风险。

尽管如此,如果您担心HTTP / 1.0客户端(它们不支持vhost并且可能无法访问您的页面),那么您应该包含HTML链接到303响应正文中的新页面(像Apache这样的网络服务器已经这样做了。


54
2017-07-22 10:03



好建议 - Pacerier
虽然303在技术上是正确的(并且是我使用的),现代浏览器(我只是在Chrome 26上尝试过) 仍然 不遵循规范对POST的302响应,所以它似乎在现代网络302 === 303。 - Raman
@Raman:没错,我认为不会有任何时间我们可以开始在万维网上使用302的新定义,如果有的话(那是一个非常勇敢的浏览器供应商)。 HTTP规范可以通过非Web UA按照预期在“围墙花园”中进行,因此重定向POST并不是完全失败的原因。 - Lee Kowalkowski
@LeeKowalkowski关于非网络UA的好处。 - Raman
HTTP/1.0 实际上,客户并不罕见。例如 wget 得到了他的 HTTP/1.1 仅在2011年支持,并且尚未对Debian稳定发布。如果您创建了一个API,并且您认为它是便携式和机器人友好型的,请为您的应用程序设计 HTTP/1.0。 - rr-


在大多数服务器端语言中,默认重定向机制使用302:

  • Java的 response.sendRedirect(..) 使用302
  • ASP.NET response.Redirect(..) 使用302
  • PHP header("Location: ..") 使用302
  • 回报率 redirect_to 使用302
  • 等等..

所以我更喜欢这个,而不是手动设置状态和标题。


8
2018-02-26 19:15



@dowvoters让我知道什么是错的? - Bozho
天啊,我不知道PHP的 header() 除了发送给定的头数据之外,还会做一些伏都教。与文档一起检查,+1表示提升 - Kos
和ExpressJS res.redirect(url) 默认情况下使用302 - Andy


从理论上讲,你(以及全世界)应该使用303,正如你所指出的那样。但是,大多数浏览器对302做出反应,就像他们应该对303做出反应一样。总的来说,如果你发送302或303似乎没关系。在你为303规范提供的链接中,这是一个有趣的注释:

注意:许多HTTP / 1.1前用户代理不了解303状态。当考虑与这样的客户端的互操作性时,可以替代地使用302状态代码,因为大多数用户代理对302响应做出反应,如针对303所描述的。

重要的是要注意到 -HTTP / 1.1用户代理,所以也许这一点很重要,但我现在不相信。

所以,总而言之,这取决于你(我可以打赌任何你想要的浏览器都不会改变他们对302状态的行为,因为他们害怕为用户打破互联网)。


4
2018-02-26 19:14





当提供由POST请求创建的新资源的位置时,201(“已创建”)是适当的响应。

HTTP / 1.1: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2

原子发布协议: http://tools.ietf.org/html/rfc5023#section-5.3 

这确实意味着Web浏览器可能不会重定向到新URL;用户必须按照链接转到新项目(此链接可以在响应正文中提供,也可以在位置标题中提供)。


4
2018-05-08 09:59