302 FOUND和307 TEMPORARY REDIRECT HTTP响应之间的区别是什么?

W3规范似乎表明它们都用于临时重定向,并且都不能缓存,除非响应特别允许。


当前回答

301: permanent redirect: the URL is old and should be replaced. Browsers will cache this. Example usage: URL moved from /register-form.html to signup-form.html. The method will change to GET, as per RFC 7231: "For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request." 302: temporary redirect. Only use for HTTP/1.0 clients. This status code should not change the method, but browsers did it anyway. The RFC says: "Many pre-HTTP/1.1 user agents do not understand [303]. When interoperability with such clients is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303." Of course, some clients may implement it according to the spec, so if interoperability with such ancient clients is not a real concern, 303 is better for consistent results. 303: temporary redirect, changing the method to GET. Example usage: if the browser sent POST to /register.php, then now load (GET) /success.html. 307: temporary redirect, repeating the request identically. Example usage: if the browser sent a POST to /register.php, then this tells it to redo the POST at /signup.php. 308: permanent redirect, repeating the request identically. Where 307 is the "no method change" counterpart of 303, this 308 status is the "no method change" counterpart of 301.

RFC 7231(从2014年开始)可读性很强,不会过于冗长。如果你想知道确切的答案,这本书是推荐阅读的。其他一些答案使用了1999年的RFC 2616,但没有任何变化。

RFC 7238指定308状态。它被认为是实验性的,但在2016年已经被所有主要浏览器支持。

其他回答

区别在于重定向POST, PUT和DELETE请求,以及服务器对用户代理行为的期望(RFC 2616):

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

另外,请阅读维基百科关于30x重定向代码的文章。

最初只有302个

Response What browsers should do
302 Found Redo request with new url

这个想法是:

如果你在某个位置做一个GET,你会重做你的GET到新的URL 如果你在某个位置做POST,你会重做POST到新的URL 如果你在某个位置执行PUT,你会重做PUT到新的URL 如果你在某个位置执行DELETE操作,你会对新的URL重做DELETE操作 等

不幸的是,每个浏览器都做错了。当得到302时,他们总是会在新的URL上切换到GET,而不是用相同的动词(例如,POST)重新尝试请求:

Mosaic做错了 Netscape复制了Mosaic中的漏洞;所以他们错了 ie浏览器复制了Netscape的漏洞;所以他们错了

这实际上是错误的。

所有浏览器都错了302。303和307就这样诞生了。

Response What browsers should do What browsers actually do
302 Found Redo request with new url GET with new url
303 See Other GET with new url GET with new url
307 Temporary Redirect Redo request with new url Redo request with new url

图表形式

5种不同的重定向:

╔═══════════╦════════════════════════════════════════════════╗
║           ║                Switch to GET?                  ║
║           ╟────────────────────────┬───────────────────────╢
║ Temporary ║          No            │         Yes           ║
╠═══════════╬════════════════════════╪═══════════════════════╣
║ No        ║ 308 Permanent Redirect │ 301 Moved Permanently ║
╟───────────╟────────────────────────┼───────────────────────╢
║ Yes       ║ 307 Temporary Redirect │ 303 See Other         ║
║           ║ 302 Found (intended)   │ 302 Found (actual)    ║
╚═══════════╩════════════════════════╧═══════════════════════╝

另外:

Response Switch to get? Temporary?
301 Moved Permanently No No
302 Found (intended) No Yes
302 Found (actual) Yes Yes
303 See Other Yes Yes
307 Temporary Redirect No Yes
308 Permanent Redirect No No

301: permanent redirect: the URL is old and should be replaced. Browsers will cache this. Example usage: URL moved from /register-form.html to signup-form.html. The method will change to GET, as per RFC 7231: "For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request." 302: temporary redirect. Only use for HTTP/1.0 clients. This status code should not change the method, but browsers did it anyway. The RFC says: "Many pre-HTTP/1.1 user agents do not understand [303]. When interoperability with such clients is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303." Of course, some clients may implement it according to the spec, so if interoperability with such ancient clients is not a real concern, 303 is better for consistent results. 303: temporary redirect, changing the method to GET. Example usage: if the browser sent POST to /register.php, then now load (GET) /success.html. 307: temporary redirect, repeating the request identically. Example usage: if the browser sent a POST to /register.php, then this tells it to redo the POST at /signup.php. 308: permanent redirect, repeating the request identically. Where 307 is the "no method change" counterpart of 303, this 308 status is the "no method change" counterpart of 301.

RFC 7231(从2014年开始)可读性很强,不会过于冗长。如果你想知道确切的答案,这本书是推荐阅读的。其他一些答案使用了1999年的RFC 2616,但没有任何变化。

RFC 7238指定308状态。它被认为是实验性的,但在2016年已经被所有主要浏览器支持。

另外,对于服务器管理员,重要的是要注意,如果使用307重定向,浏览器可能会向用户显示提示。

例如,Firefox和Opera会要求用户允许重定向,而Chrome、IE和Safari会透明地进行重定向。

*每个防弹SSL和TLS(第192页)。

在某些用例中,攻击者可能会滥用307重定向来了解受害者的凭据。

更多信息可以在OAuth 2.0的全面正式安全分析的3.1节中找到。

上述论文的作者建议如下:

Fix. Contrary to the current wording in the OAuth standard, the exact method of the redirect is not an implementation detail but essential for the security of OAuth. In the HTTP standard (RFC 7231), only the 303 redirect is defined unambigiously to drop the body of an HTTP POST request. All other HTTP redirection status codes, including the most commonly used 302, leave the browser the option to preserve the POST request and the form data. In practice, browsers typically rewrite to a GET request, thereby dropping the form data, except for 307 redirects. Therefore, the OAuth standard should require 303 redirects for the steps mentioned above in order to fix this problem.