搞不清楚的302、303和307返回码

时间:2021-07-06 16:21:34

title: "搞不清楚的302、303和307"
date: 2015-04-17 14:26:08
tags: http
---

直接看 HTTP/1.0 规范

302 Moved Temporarily(临时移动)

The requested resource resides temporarily under a different URL. Since the redirection may be altered on occasion, the client should continue to use the Request-URI for future requests.

所请求的资源暂时位于另一个 URL。客户端将来应该继续使用原来的 url 来发送请求,因为这次重定向是偶尔发生的。

The URL must be given by the Location field in the response. Unless it was a HEAD request, the Entity-Body of the response should contain a short note with a hyperlink to the new URI(s).

响应报文必须给出 Location 首部,除非这请求使用 HEAD 方法,响应的正文应该包含对新的 url 的简短说明。

If the 302 status code is received in response to a request using the POST method, the user agent must not automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

如果你用 POST 方法发送请求,然后收到响应的状态码为 302 的话,那么客户端一定要在用户明确的情况下才能重定向到新的地址,因为重定向可能会改变原请求的一些条件。

Note: When automatically redirecting a POST request after receiving a 302 status code, some existing user agents will erroneously change it into a GET request.

备注:在 POST 方法请求返回 302 状态码,然后自动重定向时,有些客户改用 GET 方法,这是错误的。

再看 HTTP/1.1 规范

与 http/1.0 的 302 的不同部分使用 斜体 表示

302 Found

1.1 把 302 的描述改为 Found,所以我认为 1.1 强调了对待 302 的含糊性,想要废弃它。

The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.

所请求的资源暂时位于另一个 URL。客户端将来应该继续使用原来的 url 来发送请求,因为这次重定向是偶尔发生的。当且仅当存在 Cache-Control 或 Expires 响应头部时才允许客户端缓存该响应

The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

响应报文必须给出 Location 首部表示新地址,除非这请求使用 HEAD 方法,响应的正文应该包含对新的 url 的简短说明。

If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

如果你用 POST 方法发送请求,然后收到响应的状态码为 302 的话,那么客户端一定要在用户明确的情况下才能重定向到新的地址,因为重定向可能会改变原请求的一些条件。

Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.

备注:RFC 1945 和 RFC 2068 说明了客户端在重定向请求时不允许改变原请求使用的方法。大多数客户端接收到 302 之后,对新的 URL 发起 GET 请求,把 302 的响应当作 303 来处理了。为了处理这种含糊的情况,添加 303 和 307 状态码来分清楚客户端该做出哪种反应。

303 See Other

The response to the request can be found under a different URI and SHOULD be retrieved using a GET method on that resource. This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource. The new URI is not a substitute reference for the originally requested resource. The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable.

请求的资源可以在另一个地址找到,客户端应该使用 GET 方法重定向来获取该资源。它的主要目的是让后台处理完 POST 请求后能够把客户端引导到一个选定的资源。这个新地址并不能直接替代最初的 POST 请求。带 303 的响应本身不应该被缓存,但是后续的重定向资源是可缓存的。

译者: 例如表单发送请求创建了用户后,后台创建完用户后重定向引导客户端到用户列表界面。

The different URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

响应报文必须给出 Location 首部表示新地址,除非这请求使用 HEAD 方法,响应的正文应该包含对新的 url 的简短说明。

Note: Many pre-HTTP/1.1 user agents do not understand the 303 status. 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.

备注:很多 http/1.1 之前的客户端没有正确理解 303。如果你担心跟这类浏览器交互的话,你可以用 302 来替代,大多数客户端处理 302 的方式就跟上面描述处理 303 的一样。

307 Temporary Redirect

The requested resource resides temporarily under a different URI. Since the redirection MAY be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.

所请求的资源暂时位于另一个 URL。客户端将来应该继续使用原来的 url 来发送请求,因为这次重定向是偶尔发生的。当且仅当响应包含 Cache-Control 或 Expires 首部时,才可以缓存。

The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s) , since many pre-HTTP/1.1 user agents do not understand the 307 status. Therefore, the note SHOULD contain the information necessary for a user to repeat the original request on the new URI.

响应报文必须给出 Location 首部表示新地址,除非这请求使用 HEAD 方法,响应的正文应该包含对新的 url 的简短说明。因为很多 http/1.1 之前的客户端无法理解 307,所以,返回的说明有必要让用户知道要将来依然要用原始的url来请求,而不是新的地址。

If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

客户端收到状态码为 307 的响应后,想用 GET 和 HEAD 以外的方法重定向的话,那么一定要在用户明确的情况下才能重定向到新的地址,因为重定向可能会改变原请求的一些条件。

总结

  • 303307 是 1.1 新增的,为了细化客户端对 302 含糊的处理方式
  • 1.1 的 302 和 1.0 的 302 的规范是一样的
  • 很多浏览器对 302、303 的处理方式是跟 1.1 的 303 规范一样
  • 规范:POST->307->用户明确->POST
  • 规范:POST->303->GET
  • 303 描述为 see other,我理解场景可以是
    • 你要处理的事情做完了,你可以去这里看看你刚才处理的结果(请求创建用户->用户列表)
    • 你要查看的东西是英文版,但是你的客户端是中文,你还是去看中文吧
    • ......
  • 307 的描述为 Temporary Redirect,我理解的场景可以是
    • 服务器升级了,创建用户得用这个 api 地址
    • ......