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

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


当前回答

307和302之间的唯一区别是307保证在重定向请求发出时方法和主体不会被更改。对于302,一些旧客户端错误地将方法更改为GET:使用非GET方法和302的行为在Web上是不可预测的,而使用307的行为是可预测的。对于GET请求,它们的行为是相同的。

参考文献:307临时重定向

其他回答

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的ACTUAL:重定向在NEW_URL上使用相同的请求方法POST

CLIENT POST OLD_URL -> SERVER 307 NEW_URL -> CLIENT POST NEW_URL

307内部重定向的一个很好的例子是当谷歌Chrome遇到一个HTTP调用到一个域,它知道需要严格的传输安全。

浏览器使用与原始调用相同的方法无缝重定向。

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年已经被所有主要浏览器支持。

302 is temporary redirect, which is generated by the server whereas 307 is internal redirect response generated by the browser. Internal redirect means that redirect is done automatically by browser internally, basically the browser alters the entered url from http to https in get request by itself before making the request so request for unsecured connection is never made to the internet. Whether browser will alter the url to https or not depends upon the hsts preload list that comes preinstalled with the browser. You can also add any site which support https to the list by entering the domain in the hsts preload list of your own browser which is at chrome://net-internals/#hsts.One more thing website domains can be added by their owners to preload list by filling up the form at https://hstspreload.org/ so that it comes preinstalled in browsers for every user even though I mention you can do particularly for yourself also.

Let me explain with an example: I made a get request to http://www.pentesteracademy.com which supports only https and I don't have that domain in my hsts preload list on my browser as site owner has not registered for it to come with preinstalled hsts preload list. GET request for unsecure version of the site is redirected to secure version(see http header named location for that in response in above image). Now I add the site to my own browser preload list by adding its domain in Add hsts domain form at chrome://net-internals/#hsts, which modifies my personal preload list on my chrome browser.Be sure to select include subdomains for STS option there. Let's see the request and response for the same website now after adding it to hsts preload list. you can see the internal redirect 307 there in response headers, actually this response is generated by your browser not by server. Also HSTS preload list can help prevent users reach the unsecure version of site as 302 redirect are prone to mitm attacks. Hope I somewhat helped you understand more about redirects.

最初只有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