302 FOUND和307 TEMPORARY REDIRECT HTTP响应之间的区别是什么?
W3规范似乎表明它们都用于临时重定向,并且都不能缓存,除非响应特别允许。
302 FOUND和307 TEMPORARY REDIRECT HTTP响应之间的区别是什么?
W3规范似乎表明它们都用于临时重定向,并且都不能缓存,除非响应特别允许。
当前回答
区别在于重定向POST, PUT和DELETE请求,以及服务器对用户代理行为的期望(RFC 2616):
注意:RFC 1945和RFC 2068指定不允许客户端这样做 更改重定向上的方法 请求。然而,大多数现有用户 代理实现将302视为 这是303响应,执行一个 GET Location字段值 不管最初的请求是什么 方法。状态代码是303和307 已添加的服务器,希望 明确地说明是哪一种 的反应是预期的 客户端。
另外,请阅读维基百科关于30x重定向代码的文章。
其他回答
区别在于重定向POST, PUT和DELETE请求,以及服务器对用户代理行为的期望(RFC 2616):
注意:RFC 1945和RFC 2068指定不允许客户端这样做 更改重定向上的方法 请求。然而,大多数现有用户 代理实现将302视为 这是303响应,执行一个 GET Location字段值 不管最初的请求是什么 方法。状态代码是303和307 已添加的服务器,希望 明确地说明是哪一种 的反应是预期的 客户端。
另外,请阅读维基百科关于30x重定向代码的文章。
307的出现是因为用户代理采用了一种事实上的行为,即接收到302响应的POST请求并向Location响应头发送GET请求。
这是不正确的行为——只有303才会导致POST转换为GET。如果最初的POST请求返回302,用户代理在请求新URL时应该(但不)坚持使用POST方法。
引入307是为了允许服务器向用户代理清楚地表明,当客户端遵循Location响应报头时,不应该对方法进行更改。
307内部重定向的一个很好的例子是当谷歌Chrome遇到一个HTTP调用到一个域,它知道需要严格的传输安全。
浏览器使用与原始调用相同的方法无缝重定向。
最初只有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 |
||
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年已经被所有主要浏览器支持。