302 FOUND
和 307 TEMPORARY REDIRECT
HTTP 响应之间有什么区别?
W3 规范 表明它们都用于临时重定向,并且除非响应明确允许,否则两者都不能被缓存。
307诞生是因为用户代理采用了一种默认行为,即将收到302响应的POST请求发送到Location响应头的GET请求。
那是不正确的行为——只有303应该导致POST变成GET。 如果原始的POST请求返回302,则用户代理应该(但没有)坚持使用POST方法请求新URL。
307被引入是为了让服务器向用户代理明确表示,在遵循Location响应头时,客户端不应进行方法更改。
307 内部重定向
的例子是当 Google Chrome 遇到一个它知道需要严格传输安全 (Strict Transport Security) 的域名的 HTTP 调用时。浏览器使用与原始调用相同的方法无缝重定向。
/register-form.html
移动到signup-form.html
。/register.php
发送POST,则现在加载(GET)/success.html
。/register.php
发送了POST请求,那么这会告诉它在/signup.php
重新执行POST。RFC 7231(来自2014年)非常易读且不冗长。如果您想要确切的答案,建议仔细阅读该文档。其他一些答案使用了1999年的RFC2616,但是并没有任何更改。
RFC 7238指定了308状态。虽然它被认为是实验性的,但它已经在2016年得到了所有主流浏览器的支持。
原本只有302
响应 | 浏览器应该做什么 |
---|---|
302 Found | 用新的URL重新发起请求 |
思路是:
GET
,则需要使用新的URL重新发起GET
请求POST
,则需要使用新的URL重新发起POST
请求PUT
,则需要使用新的URL重新发起PUT
请求DELETE
,则需要使用新的URL重新发起DELETE
请求不幸的是,所有浏览器都做错了。当收到302
时,它们总是会切换到使用GET
方法请求新的URL,而不是重试相同的方法(例如,POST
):
这样就形成了事实上的错误。
所有浏览器都处理302
错误。因此,303
和307
被创建了。
响应 | 浏览器应该做什么 | 浏览器实际上做了什么 |
---|---|---|
302 Found | 用新的URL重新发起请求 | 使用新URL进行GET请求 |
303 See Other | 使用新的URL重新发起GET请求 | 使用新URL进行GET请求 |
307 Temporary Redirect | 用新的URL重新发起请求 | 使用新的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) ║
╚═══════════╩════════════════════════╧═══════════════════════╝
或者:
响应 | 是否需要更改? | 临时的? |
---|---|---|
301 永久移动 |
No | No |
302 找到 |
||
302 找到 (实际) |
是的 | 是的 |
303 查看其他 |
是的 | 是的 |
307 临时重定向 |
No | 是的 |
308 永久重定向 |
No | No |
预期的302重定向:重定向使用相同的请求方法POST在NEW_URL上
CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT POST NEW_URL
在302、303状态码的情况下,实际操作是将请求方法从POST更改为GET并重定向到NEW_URL
CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
CLIENT POST OLD_URL -> SERVER 303 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
307的实际情况:重定向使用相同的请求方法POST在NEW_URL上。
CLIENT POST OLD_URL -> SERVER 307 NEW_URL -> CLIENT POST NEW_URL
对于服务器管理员而言,值得注意的是,如果使用307重定向,浏览器可能会向用户发出提示。
例如*,Firefox和Opera会要求用户允许重定向,而Chrome、IE和Safari则会透明地执行重定向。
*参见Bulletproof SSL and TLS(第192页)。
302
。Chrome 30、IE10都如此。这成为了事实上的错误实现;由于许多网站错误地发出302,因此无法更改该问题。实际上,ASP.NET MVC 错误地发出302,而这取决于浏览器错误地处理它这一事实。 - Ian Boyd303
也是在 HTTP 1.1 规范中与307
一起引入的,因此允许向后兼容 HTTP 1.0 用户代理。当然,真正的问题是现在我们是否仍然应该处理 HTTP 1.0 用户代理? - ewanm89Response.RedirectSeeOther
),如果客户端不是 1.1 版本(例如GET /foo.html
,GET /foo.html HTTP/1.0
),则发出传统的302
。 - Ian Boyd