217

As far as I understood there are two places where to set the content type:

  1. The client sets a content type for the body he is sending to the server (e.g. for post)
  2. The server sets a content type for the response.

Does this mean I don't have to or should not set a content type for all my get requests (client side). And if I can or should what content type would that be?

Also I read in a few posts that the content type of the client specifies what type of content the client would like to receive. So maybe my point 1 is not right?

lospejos
  • 1,976
  • 3
  • 19
  • 35
Martin Flucka
  • 3,125
  • 5
  • 28
  • 44

7 Answers7

164

According to the RFC 7231 section 3.1.5.5:

A sender that generates a message containing a payload body SHOULD generate a Content-Type header field in that message unless the intended media type of the enclosed representation is unknown to the sender. If a Content-Type header field is not present, the recipient MAY either assume a media type of "application/octet-stream" ([RFC2046], Section 4.5.1) or examine the data to determine its type.

It means that the Content-Type HTTP header should be set only for PUT and POST requests.

Community
  • 1
  • 1
Epoc
  • 7,208
  • 8
  • 62
  • 66
  • 15
    @Epoc, The quoted message is at best implicit. It **doesn't actually say** that messages without entity-body `SHOULD NOT` include a Content-Type. Do we have an explicit quote? – Pacerier Dec 10 '14 at 11:53
  • 3
    @Pacerier please don't strike out the core conclusion of somebody else's answer, even if it's false. I agree that Epoc's answer is wrong - nothing in the section he's quoted backs up his answer's conclusion, and it deserves to be downvoted. But that doesn't mean you should edit the answer to eliminate its core premise and thereby totally change its meaning. – Mark Amery Oct 19 '17 at 12:57
  • 18
    I think you guys are reading @Epoc's words too literally. Sure, the quoted section does not *mean* what he says it means. But I think the conclusion is correct in the context of the OPs question. The OP is looking for clarity as to when it makes sense to include Content-Type and when it does not. Epoc provided information about how the header is used, and drew the conclusion that any reasonable developer would: you "ought to" use a content-type for requests that have payload bodies (mainly PUT and POST) and you probably "ought not" use it in places where it isn't useful, like GET or HEAD, etc. – JVMATL Jan 24 '18 at 21:03
  • 3
    Your post statement, "It means . . ." - is a stretch. – Adrian Bartholomew Aug 28 '18 at 13:31
  • 2
    @Pacerier it doesn't really need to, however it does say that "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." -- I still interpret this as "should not" (best practice) and not an explicit "must not", this just suggests that you shouldn't expect consistency across server implementations. But yes, if you do include a payload, you "should" also include `Content-Type`; it's just a payload in `GET` is not part of the standard. – patricknelson May 05 '21 at 03:19
  • Granted, that interpretation (which is used by, say, Postman) is definitely open to discussion. For instance, you _may_ wish to use a GET request to retrieve `application/json` (as opposed to text/plain). You _may_ send an `Accept:` header for that — which would be perhaps more correct — but not every system does peek at that header. One just _assumes_ that if the request requires XML, then XML should be the answer; ditto for HTML, plain text, JSON, and Whatever-Format-We-Come-Up-With-Tomorrow. – Gwyneth Llewelyn Aug 01 '23 at 18:59
70

GET requests should not have content-type because they do not have request entity (that is, a body)

shA.t
  • 16,580
  • 5
  • 54
  • 111
Dmitry Negoda
  • 2,894
  • 2
  • 18
  • 15
  • 42
    @Dmitry, **Citation needed**, otherwise it stands as an assumption, not as a fact. – Pacerier Dec 10 '14 at 11:50
  • 6
    While I agree that the spec doesn't say you can't have Content-Type on a GET, .Net seems to enforce it in it's HttpClient. See https://stackoverflow.com/questions/10679214/how-do-you-set-the-content-type-header-for-an-httpclient-request – Adam Feb 02 '18 at 13:55
  • 1
    The spec doesn't even enforce GET requests to not have body.... – pishpish Feb 02 '21 at 09:53
  • 1
    I would agree with "should not" because the behavior is not defined (per the spec), that's all. Again, "should" isn't the same as "must not". Just don't expect consistent behavior because, again per spec: "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." But, if you're gonna do it, then `Content-Type` would make sense, sure. – patricknelson May 05 '21 at 03:15
  • 1
    I agree with this answer. However, recently I was calling a REST API GET endpoint that refused to reply 200 unless header `Content-Type` was present. Somewhat insane to me... – kevinarpe Dec 02 '22 at 07:06
  • As said, very correctly: _should not_, but not really _must not_. There's a world of difference between both! – Gwyneth Llewelyn Aug 01 '23 at 19:10
42

GET requests can have "Accept" headers, which say which types of content the client understands. The server can then use that to decide which content type to send back.

They're optional though.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1

Matthew Wilson
  • 3,861
  • 21
  • 14
  • Very optional indeed. I'm writing in the future, and even nowadays, many API, many APIs simply don't look at the `Accept` header at all. They _do_, however, look at `Content-Type` to see what format the requester expects to receive. Now I realise that's why _some_ APIs that use GET often use a query string to pass a parameter for the format... – Gwyneth Llewelyn Aug 01 '23 at 19:02
36

The accepted answer is wrong. The quote is correct, the assertion that PUT and POST must have it is incorrect. There is no requirement that PUT or POST actually have additional content. Nor is there a prohibition against GET actually having content.

The RFCs say exactly what they mean .. IFF your side (client OR origin server) will be sending additional content, beyond the HTTP headers, it SHOULD specify a Content-Type header. But note it is allowable to omit the Content-Type and still include content (say, by using a Content-Length header).

user4157069
  • 379
  • 3
  • 2
10

Short answer: Most likely, no you do not need a content-type header for HTTP GET requests. But the specs does not seem to rule out a content-type header for HTTP GET, either.

Supporting materials:

  1. "Content-Type" is part of the representation (i.e. payload) metadata. Quoted from RFC 7231 section 3.1:

    3.1. Representation Metadata

    Representation header fields provide metadata about the representation. When a message includes a payload body, the representation header fields describe how to interpret the representation data enclosed in the payload body. ...

    The following header fields convey representation metadata:

    +-------------------+-----------------+
    | Header Field Name | Defined in...   |
    +-------------------+-----------------+
    | Content-Type      | Section 3.1.1.5 |
    | ...               | ...             |
    

    Quoted from RFC 7231 section 3.1.1.5(by the way, the current chosen answer had a typo in the section number):

    The "Content-Type" header field indicates the media type of the associated representation

  2. In that sense, a Content-Type header is not really about an HTTP GET request (or a POST or PUT request, for that matter). It is about the payload inside such a whatever request. So, if there will be no payload, there needs no Content-Type. In practice, some implementation went ahead and made that understandable assumption. Quoted from Adam's comment:

    "While ... the spec doesn't say you can't have Content-Type on a GET, .Net seems to enforce it in it's HttpClient. See this SO q&a."

  3. However, strictly speaking, the specs itself does not rule out the possibility of HTTP GET contains a payload. Quoted from RFC 7231 section 4.3.1:

    4.3.1 GET

    ...

    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, if your HTTP GET happens to include a payload for whatever reason, a Content-Type header is probably reasonable, too.

Community
  • 1
  • 1
RayLuo
  • 17,257
  • 6
  • 88
  • 73
  • What about if the HTTP GET request does _not_ include any payload, but wants to receive a response in, say, JSON or XML, but the API it's calling couldn't care less about what the client's `Accept` header say? This is an issue open to interpretation... – Gwyneth Llewelyn Aug 01 '23 at 19:12
0

I found that article very useful in clarifying the 'Content-Type' concept, you can check it out and at the end, there is a list of the common values of the HTTP Content-type header.

https://www.geeksforgeeks.org/http-headers-content-type/

-2

The problem with not passing over the content-type on a GET message is that sure the content-type is irrelevant because the server side determines the content anyway. The problem that I have encountered is that there are now a lot of places that set up their webservices to be smart enough to pick up the content-type that you pass and return the response in the 'type' that you request. Eg. we are currently messaging with a place that defaults to JSON, however, they have set their webservice up so that if you pass a content-type of xml they will then return xml rather than their JSON default. Which I think going forward is a great idea

Leeroy
  • 17
  • 1
  • Why exactly this was downvoted is a mystery. @Leeroy is really just stating what APIs do _de facto_. `curl` has no problem in setting whatever `Content-Type` header one prefers, even with GET, and that allows the API to cleverly figure out what format to send back. While this is _not_ the way it should be — the `Accept` header is to be used for telling the server what content type is acceptable — it is, indeed, used by quite a lot of clever APIs. Note that it's just a question of interpreting the specs; they do _not_ **explicitly forbid** this kind of mechanism, and, therefore, it _is_ used. – Gwyneth Llewelyn Aug 01 '23 at 19:08