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

Peo*_*Sea 39 http-headers

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

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

Dav*_*bin 41

restclientREST控制台都不支持这个,但卷曲确实如此.

原始HTTP 1.1规范说,在第4.3节

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

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

第5.2节

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

9.3节

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

这一点一起表明,在处理GET请求时,服务器不需要检查Request-URI和Host头字段之外的任何其他内容.

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

  • 需要注意的是,虽然 HTTP 规范没有明确禁止在 GET 请求中使用主体,但这毫无意义。HTTP 也不会阻止你在进行 POST 请求时拍手,但不会影响其操作。 (2认同)

ale*_*dov 13

旧的RFC2616已被取代,并被多个RFC(7230-7237)取代.

关于HTTP/1.1的RFC 7230清楚地说明了消息体:

HTTP消息的消息体(如果有的话)用于携带该
请求或响应的有效负载主体.
除非已
应用传输编码,否则消息正文与有效负载主体相同,如第3.3.1节所述.

 message-body = *OCTET
Run Code Online (Sandbox Code Playgroud)

消息中允许消息正文的规则因请求和响应而异.

请求中存在消息体由
Content-Length或Transfer-Encoding头字段指示. 请求消息
成帧独立于方法语义
,即使该方法没有
为消息体定义任何用途.

所以新标准清楚地回答了最初的问题.但是有一些旧的软件可以忽略消息体进入GET请求,所以你需要谨慎并检查这种情况.

  • 你说"清楚"两次,但对我来说并不是那么清楚.我想你在说"是否有一个主体完全取决于'Content-Length`和/或`Transfer-Encoding`标题的存在"? (3认同)

Kra*_*n P 8

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

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


Mar*_*ele 5

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

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

来自 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.
Run Code Online (Sandbox Code Playgroud)

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

RFC 7231 也提到了这个问题

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.
Run Code Online (Sandbox Code Playgroud)

因此,在我看来,这意味着您可以向 GET 请求添加消息正文(这应该可以回答您的原始问题),但您必须小心。规范中提到的案例并不是您必须注意的唯一案例,许多工具、客户端和服务器根本不期待消息正文,并且可能会出现错误行为。例如,在 Chrome 中,XMLHttpRequest 将删除 GET 的消息正文。

另一个问题是缓存问题。根据RFC 7234

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.
Run Code Online (Sandbox Code Playgroud)

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

最后,我认为如果可能,您应该避免在 GET 中使用消息正文,除非

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