这个陈述是否正确? HTTP GET方法始终没有消息体

时间:2011-03-07 06:31:02

标签: http-headers

这句话是否正确? HTTP GET方法始终没有消息体。 我没有发现RFC2616的任何部分明确说出这一点。

如果不是这样,那么在什么情况下Http GET请求会包含一个消息正文

3 个答案:

答案 0 :(得分:39)

restclientREST console都不支持此功能,但curl支持此功能。

original HTTP 1.1 specification在第4.3节中说明

  

如果请求方法的规范(第5.1.1节)不允许在请求中发送实体主体,则消息体不得包含在请求中。

Section 5.1.1将我们重定向到第9.x节的各种方法。他们都没有明确禁止包含消息体。然而...

Section 5.2

  

Internet请求标识的确切资源是通过检查Request-URI和Host头字段来确定的。

Section 9.3

  

GET方法意味着检索Request-URI标识的任何信息(以实体的形式)。

这一起表明,当处理GET请求时,服务器不是 required 来检查Request-URI和Host头字段之外的任何其他内容。

总之,HTTP规范并不会阻止您使用GET发送消息体,但是如果所有服务器都不支持它,那么它就不会让我感到惊讶。

答案 1 :(得分:7)

我在elasticsearch中遇到过这个问题,其中带有消息体的GET请求用于测试分析器 - https://www.elastic.co/guide/en/elasticsearch/guide/master/analysis-intro.html

本质上,这是一个不会在服务器端更改任何内容的请求,但它需要将长文本消息作为输入传递。看起来像是在消息体中使用GET请求。

答案 2 :(得分:3)

认为规范允许您添加邮件正文,因此您的问题的答案应该是(但有警告)。

让我们首先检查规范(我引用RFC 7231RFC 7232RFC 7234,因为其他答案中提到的RFC 2616已经被他们淘汰了)。

From RFC 7230

The presence of a message body in a request is signaled by a
Content-Length or Transfer-Encoding header field. Request message
framing is independent of method semantics, even if the method does
not define any use for a message body.

请注意,部分“如果请求方法的规范(第5.1.1节)不允许在请求中发送实体主体,则消息主体不得包含在请求中。”目前在旧的RFC 2616中已被删除。

RFC 7231 says this on the subject

A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.

所以,在我看来,这意味着你可以在GET请求中添加一个消息体,(这应该回答你原来的问题),但是你必须要小心。规范中提到的案例并不是您必须注意的唯一案例,许多工具,客户端和服务器根本不期望邮件正文并且可能行为不端。例如,在Chrome中,XMLHttpRequest将删除GET的邮件正文。

另一个问题是缓存问题。根据{{​​3}}。

The primary cache key consists of the request method and target URI   
[...]
If a request target is subject to content negotiation, its cache
entry might consist of multiple stored responses, each differentiated
by a secondary key for the values of the original request's selecting
header fields.

这意味着具有不同主体但相同网址(以及可能选择的标头)的请求将被视为具有相同的缓存响应,即使邮件正文先前已正确转发到服务器。

最后,我认为如果可能的话,你应该避免在GET中使用消息体,除非

  • 您控制客户端
  • 您控制服务器
  • 您知道潜在的代理,缓存可能会妨碍
  • 您在响应中禁用缓存(实际上您可以(ab)使用标头来缓存,但我没有正确调查这个想法。)