302和307重定向之间有什么区别?


Answers:


99

所不同的关注重定向POSTPUTDELETE请求和服务器的期望是为用户代理行为(什么RFC 2616):

注意:RFC 1945和RFC 2068指定不允许客户端更改重定向请求的方法。但是,大多数现有的用户代理实现都将302视为303响应,无论原始请求方法如何,都对Location字段值执行GET。已为希望明确弄清客户端期望哪种反应的服务器添加了状态代码303和307。

另外,请阅读有关30x重定向代码的 Wikipedia文章。


因此,从解析器/代理/浏览器的角度来看,我们可以简单地将302和307视为相同的权利?(可以使用完全相同的代码来处理这两种情况,而无需进一步区分?)
Pacerier,2016年

不可以-您可以将302和303视为相同,但307不同。
Quentin Skousen

@kkhugs,没有办法,需要get 1.0浏览器来执行get-302,就像在1.1浏览器中执行get-307一样。要求1.0浏览器以与get-302相同的方式执行post-302,不同之处在于它必须首先要求用户确认才能继续,并且该方法必须为post。
Pacerier '17

需要1.1浏览器来执行get-302的方式与执行get-307的方式相同。
Pacerier '17

161

之所以出现307,是因为用户代理实际上被采取了以下行动:接收302响应的POST请求,然后将GET请求发送到Location响应头。

那是不正确的行为- 只有 303应该导致POST变成GET。如果原始POST请求返回302,则用户代理在请求新URL时应该(但不要)坚持使用POST方法。

307被引入到允许服务器以明确的用户代理的方法的变化应被客户端之后的位置响应头时制成。


3
用户代理响应不正确的任何示例吗?通常是很少一部分访客吗?
goodguys_activate 2011年

6
@ makerofthings7所有浏览器处理302不正确。Chrome 30,IE10。它实际上是不正确的实现。由于许多网站错误地发出了302,因此无法更改。实际上,ASP.net MVC错误地发出了302,具体取决于浏览器处理不正确的事实。
伊恩·博伊德

1
@IanBoyd这样做的唯一原因是,框架303也是307HTTP 1.1规范中引入的,因此允许与HTTP 1.0用户代理向后兼容。当然,真正的问题是我们现在是否仍应该处理HTTP 1.0用户代理?
ewanm89

1
@ ewanm89似乎是该框架可以创建正确命名的响应方法(例如Response.RedirectSeeOther),如果客户端不是1.1(例如GET /foo.htmlGET /foo.html HTTP/1.0)然后发出遗产302
伊恩·博伊德

重定向时看起来像302 = 303。
vee

60

实际应用中的一个很好的例子307 Internal Redirect是,当Google Chrome浏览器遇到对其要求严格传输安全性的域的HTTP调用时。

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

HTST 307内部重定向


2
您知道Google何时实施此功能吗?
蒂梅2015年

2
是的,这就是我看到的情况-我们的服务器未发送该消息-在chrome devtools中看起来像是,但是只是chrome在进行重定向,因为我们有严格的传输安全标头
mike nelson

16

流程图

  • 301:永久重定向:URL旧,应替换。浏览器将对此进行缓存。
    用法示例: URL从/register-form.html移到signup-form.html
    根据RFC 7231,该方法将更改为GET:“由于历史原因,用户代理可以针对后续请求将请求方法从POST更改为GET。”
  • 302:临时重定向。仅用于HTTP / 1.0客户端。此状态码不应更改方法,但是浏览器还是这样做。RFC表示:“许多HTTP / 1.1之前的用户代理不理解[303]。当需要考虑与此类客户端的互操作性时,可以改用302状态代码,因为大多数用户代理都对302响应做出了反应,如此处所述303。” 当然,某些客户可能会根据规范实施它,因此,如果与真正的客户之间的互操作性不是真正的问题,则303会更好地获得一致的结果。
  • 303:临时重定向,将方法更改为GET。
    用法示例:如果浏览器将POST发送到/register.php,则现在加载(GET)/success.html
  • 307:临时重定向,同样地重复请求。
    用法示例:如果浏览器将POST发送到/register.php,则告诉它在处重做POST /signup.php
  • 308:永久重定向,同样地重复请求。其中307是303的“无方法更改”对应项,而此308状态是301的“无方法更改”对应项。

RFC 7231(自2014年起)具有很好的可读性,并且不太冗长。如果您想知道确切的答案,建议阅读。其他一些答案使用的是1999年的RFC 2616,但没有任何变化。

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


不弃用302。
朱利安·雷施克

@JulianReschke维基百科说:“ 302已被303和307取代。” 也许是因为我不是母语人士,但对我而言(在此情况下)被取代和弃用的含义是相同的:使用303或307,但不使用302。我读错了吗?
卢克,

维基百科对此有发言权的假设是错误的。如果不赞成使用302,HTTP会这样说。
朱利安·雷施克

@JulianReschke公平,我带到了源头和waddayaknow?你是完全正确的。RFC实际上是很容易理解的,实际上,他们甚至在某些情况下建议302。上面提到的RFC的“更新者”和“过时的”都不是关于状态码的,所以我想这个1999年的文档确实是我们最新的文档。我将更新我的答案。
卢克,

相关的是IANA状态代码注册中心,因此在此情况下为RFC7231。–
朱利安·

8

预期为302:重定向对NEW_URL使用相同的请求方法POST

CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT POST NEW_URL

302、303的“ ACTUAL”:将更改请求方法从POST重定向到NEW_URL上的GET

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

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

2

302是由服务器生成的临时重定向,而307是由浏览器生成的内部重定向响应。内部重定向意味着重定向是由浏览器在内部自动完成的,基本上,浏览器会在发出请求之前自行在get请求中将输入的URL从http更改为https,因此永远不会向Internet发出不安全连接的请求。浏览器是否将URL更改为https取决于浏览器预安装的hsts预加载列表。您也可以通过在浏览器的hsts预加载列表中输入chrome:// net-internals /#hsts中的域,将支持https的任何站点添加到列表中。所有者可以添加其他网站域通过在https://hstspreload.org/上填写表格来预加载列表这样,即使我提到您也可以自己为自己做,它还是为每个用户预装在浏览器中。


让我举一个例子来说明:
我向http://www.pentesteracademy.com发送了一个get请求,该请求仅支持https,并且我的浏览器的hsts预载列表中没有该域,因为网站所有者尚未注册附带预装的hsts预加载列表。 针对网站的不安全版本的GET请求被重定向到安全版本(请参见上图中以HTTP标头命名的location作为响应)。 现在我通过在chrome:// net-internals /#hsts的Add hsts domain表单中添加站点的域来将该站点添加到我自己的浏览器预加载列表中,这会在chrome浏览器中修改我的个人预加载列表。请确保选择include子域有STS选项。 将其添加到hsts预加载列表后,现在让我们查看对同一网站的请求和响应。请求和响应头



请求和响应头
您可以在响应标头中看到内部重定向307,实际上此响应是由您的浏览器而不是服务器生成的。
此外,HSTS预加载列表还可以帮助防止用户访问不安全版本的站点,因为302重定向容易受到mitm攻击。
希望我能在某种程度上帮助您了解有关重定向的更多信息。


2

本来只是 302

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

这个想法是:

  • 如果您是GET在某个位置进行操作,则应将您重GET做到新网址
  • 如果您是POST在某个位置进行操作,则应将您重POST做到新网址
  • 如果您是PUT在某个位置进行操作,则应将您重PUT做到新网址
  • 如果您是DELETE在某个位置进行操作,则应将您重DELETE做到新网址
  • 等等

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

  • 马赛克错了
  • Netscape复制了Mosaic中的错误;所以他们弄错了
  • Internet Explorer复制了Netscape中的错误;所以他们弄错了

实际上变成了错误。

所有浏览器都302出错了。因此303307被创建。

| 回应| 浏览器应该做什么?浏览器实际上做什么?| ------------------------ | ------------------------ --- | --------------------------- | | 找到302个| 使用新网址重做请求| 使用新网址获取| | 303查看其他| 使用新网址获取| 使用新网址获取| | 307临时重定向| 使用新网址重做请求| 使用新网址重做请求|

图表形式

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         |

1

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

例如,*和Firefox和Opera将询问用户是否允许重定向,而Chrome,IE和Safari将透明地进行重定向。

*根据防弹SSL和TLS(第192页)。


这仅适用于不安全的请求,例如POST。
朱利安·瑞施

0

在某些使用情况下,攻击者可能滥用307重定向来了解受害者的凭据。

更多信息可参见3.1节的OAuth 2.0的综合正式的安全分析

以上论文的作者提出以下建议:

固定。与OAuth标准中的当前措词相反,重定向的确切方法不是实现细节,而是对OAuth安全性至关重要。在HTTP标准(RFC 7231)中,仅明确定义了303重定向,以删除HTTP POST请求的正文。所有其他HTTP重定向状态代码,包括最常用的302,都使浏览器可以选择保留POST请求和表单数据。实际上,浏览器通常会重写为GET请求,从而除去307重定向之外的表单数据。因此,OAuth标准应该要求303重定向用于上述步骤,以解决此问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.