Send a GET request with a body in JavaScript (XMLHttpRequest)
No, it is not possible to send a GET request with a body in JavaScript.
it looks like the payload is simply not sent
That is correct. This is defined in the specification:
The
send(body)
method must run these steps:...
- If the request method is
GET
orHEAD
, set body to null.
Also a request via the Fetch API does not allow a body. From the specification:
- If either init["body"] exists and is non-null or inputBody is non-null, and request’s method is
GET
orHEAD
, then throw a TypeError.
The best would be if the API could be fixed.
If that is not possible, you could add a server-side script that you can use as a proxy that passes the requests to the API. You can than call this script with a GET request with the data in the URL instead of the body or using a POST request with a body. This script then can make the GET request with a body (as long as the chosen language supports it).
Andrei Savin
Updated on February 22, 2020Comments
-
Andrei Savin about 4 years
I have to interact with an API that takes parameters from the body of a GET request. I know this might not be the best idea, but it is the way the API was built.
When I try building a query with
XMLHttpRequest
, it looks like the payload is simply not sent. You can run this and look in the network tab; the request is sent, but there is no body (tested in latest Chrome and Firefox):const data = { foo: { bar: [1, 2, 3] } } const xhr = new XMLHttpRequest() xhr.open('GET', 'https://my-json-server.typicode.com/typicode/demo/posts') xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8') xhr.send(JSON.stringify(data))
Libraries such as axios are built on XMLHttpRequest, so they are not working either...
Is there any way to achieve this in JavaScript?
-
Andrei Savin about 5 yearsThank you for the explanation. A server-side proxy is a great suggestion.
-
John Carrell over 4 yearsNot to anger the HTTP gods but, for the record, in 2019, this spec seems dumb. I often find myself wanting to send some payload along with a request. It's possible that the payload is very large so I don't want it to be in the URL. Semantically, I'm conducting a GET request ("Give me something. Here are details of what I want. Don't create anything.") and this spec requires me to make it a POST/PUT request or use some other hackery.
-
Sergey almost 4 years@JohnCarrell The HTTP spec actually does not forbid it: "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." tools.ietf.org/html/rfc7231#section-4.3.1
-
Ivar almost 4 years@Sergey It has (AFAIK) always been allowed but in earlier versions of the specs it "SHOULD" be ignored.
-
Suamere over 3 yearsI have argued that these frameworks are broken for over a decade. REST > HTTP. If I want to Represent that I want to GET some data given certain parameters, and those parameters are either not appropriate for a Querystring either because of serialization simplicity, size, charset, security, or any other reason, I should be able to pass those parameters with a Body to a
GET
endpoint. It is not RESTfully correct to request data (even if based on parameters) by callingPUT
orPOST
. (Not that you can't expect those to return data after their respective add/update action(s)). -
Suamere over 3 years
The best would be if the API could be fixed.
- The API isn't broken. The frameworks consuming it are. -
eisenpony about 2 yearsThe trouble using the body of a GET request to describe a query is that, for historical reasons, the body is not considered by caches. A GET request describing a query then "poisons" any caches the request flowed through such that subsequent GET attempts, with a different body, will return the original result. The observed behaviour of the API then becomes dependent on the network topology. It's a defect waiting in the wings.
-
eisenpony about 2 yearsCompare to a POST, which cannot be cached, made to a /query endpoint that "creates" a new query. Best practice might be to return a new address and require a GET, but many APIs will just return the result in anticipation.