HTTP GET with request body

2018-12-30 22:27发布

I'm developing a new RESTful webservice for our application.

When doing a GET on certain entities, clients can request the contents of the entity. If they want to add some parameters (for example sorting a list) they can add these parameters in the query string.

Alternatively I want people to be able to specify these parameters in the request body. HTTP/1.1 does not seem to explicitly forbid this. This will allow them to specify more information, might make it easier to specify complex XML requests.

My questions:

  • Is this a good idea altogether?
  • Will HTTP clients have issues with using request bodies within a GET request?

http://tools.ietf.org/html/rfc2616

17条回答
情到深处是孤独
2楼-- · 2018-12-30 23:08

I wouldn't advise this, it goes against standard practices, and doesn't offer that much in return. You want to keep the body for content, not options.

查看更多
千与千寻千般痛.
3楼-- · 2018-12-30 23:10

You will likely encounter problems if you ever try to take advantage of caching. Proxies are not going to look in the GET body to see if the parameters have an impact on the response.

查看更多
ら面具成の殇う
4楼-- · 2018-12-30 23:11

What you're trying to achieve has been done for a long time with a much more common method, and one that doesn't rely on using a payload with GET.

You can simply build your specific search mediatype, or if you want to be more RESTful, use something like OpenSearch, and POST the request to the URI the server instructed, say /search. The server can then generate the search result or build the final URI and redirect using a 303.

This has the advantage of following the traditional PRG method, helps cache intermediaries cache the results, etc.

That said, URIs are encoded anyway for anything that is not ASCII, and so are application/x-www-form-urlencoded and multipart/form-data. I'd recommend using this rather than creating yet another custom json format if your intention is to support ReSTful scenarios.

查看更多
弹指情弦暗扣
5楼-- · 2018-12-30 23:12

According to XMLHttpRequest, it's not valid. From the standard:

4.5.6 The send() method

client . send([body = null])

Initiates the request. The optional argument provides the request body. The argument is ignored if request method is GET or HEAD.

Throws an InvalidStateError exception if either state is not opened or the send() flag is set.

The send(body) method must run these steps:

  1. If state is not opened, throw an InvalidStateError exception.
  2. If the send() flag is set, throw an InvalidStateError exception.
  3. If the request method is GET or HEAD, set body to null.
  4. If body is null, go to the next step.

Although, I don't think it should because GET request might need big body content.

So, if you rely on XMLHttpRequest of a browser, it's likely it won't work.

查看更多
不再属于我。
6楼-- · 2018-12-30 23:14

Elasticsearch accepts GET requests with a body. It even seems that this is the preferred way : http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/common-options.html#_request_body_in_query_string

Some client libraries (like the Ruby driver) can log the cry command to stdout in development mode and it is using this syntax extensively.

查看更多
回忆,回不去的记忆
7楼-- · 2018-12-30 23:15

While you can do that, insofar as it isn't explicitly precluded by the HTTP specification, I would suggest avoiding it simply because people don't expect things to work that way. There are many phases in an HTTP request chain and while they "mostly" conform to the HTTP spec, the only thing you're assured is that they will behave as traditionally used by web browsers. (I'm thinking of things like transparent proxies, accelerators, A/V toolkits, etc.)

This is the spirit behind the Robustness Principle roughly "be liberal in what you accept, and conservative in what you send", you don't want to push the boundaries of a specification without good reason.

However, if you have a good reason, go for it.

查看更多
登录 后发表回答