Is this statement correct? HTTP GET method always has no message body
Is this statement correct? HTTP GET m开发者_JAVA百科ethod always has no message body. I didn't find any part of RFC2616 explicitly say this.
And if this is not true, then in what circumstances will an Http GET request include a message body
Neither restclient nor REST console support this but curl does.
The original HTTP 1.1 specification says in section 4.3
A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests.
Section 5.1.1 redirects us to section 9.x for the various methods. None of them explicitly prohibit the inclusion of a message body. However...
Section 5.2 says
The exact resource identified by an Internet request is determined by examining both the Request-URI and the Host header field.
and Section 9.3 says
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.
Which together suggest that when processing a GET request, a server is not required to examine anything other that the Request-URI and Host header field.
In summary, the HTTP spec doesn't prevent you from sending a message-body with GET, but there is sufficient ambiguity that it wouldn't surprise me if it was not supported by all servers.
The old RFC2616 has been superseded and it was replaced by multiple RFCs (7230-7237).
New RFC 7230 on HTTP/1.1 clearly says about message body:
The message body (if any) of an HTTP message is used to carry the
payload body of that request or response. The message body is
identical to the payload body unless a transfer coding has been
applied, as described in Section 3.3.1.message-body = *OCTET
The rules for when a message body is allowed in a message differ for requests and responses.
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.
So new standard clearly answer the initial question. But there are some old software which can ignore message-body into GET request, so you need be cautious and check this case.
I came across this in elasticsearch where a GET request with message body is used for testing analyzers - https://www.elastic.co/guide/en/elasticsearch/guide/master/analysis-intro.html
Essentially this is a request that does not change anything on the server side, but it requires a long text message to be passed as input. Seems like an apt use of GET request with a message body.
I think the specification allows you to add a message body, so the answer to your question should be No (but with caveats).
Let's first check the specification (I am quoting from RFC 7231, RFC 7232 and RFC 7234, since RFC 2616 referred in other answers has been obsoleted by them).
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.
Note that the part "A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests." present in the old RFC 2616 has been removed.
Also 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.
So, in my opinion this means that you can add a message body to a GET request, (and this should answer your original question), but you have to be careful. The case mentioned in the specs is not the only one you have to be aware, many tools, client and servers are simply not expecting a message body and may misbehave. For example in Chrome, XMLHttpRequest will drop the message body for GETs.
Another issues is the one of caching. According to 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.
This means that requests with different bodies but same url (and possibly selected headers), will be considered having the same response by a cache, even if the message body has been previously correctly forwarded to the server.
In the end I think that if possible you should avoid using message bodies in GETs, unless
- You control the client
- You control the server
- You know of potential proxies, caches that may get in the way
- You disable caching in the response (you may in fact be able to (ab)use headers to be able to cache, but I haven't investigated properly the idea).
精彩评论