Send a GET request with a body in JavaScript (XMLHttpRequest)

22,625

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:

...

  1. If the request method is GET or HEAD, set body to null.

Also a request via the Fetch API does not allow a body. From the specification:

  1. If either init["body"] exists and is non-null or inputBody is non-null, and request’s method is GET or HEAD, 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).

Share:
22,625
Andrei Savin
Author by

Andrei Savin

Updated on February 22, 2020

Comments

  • Andrei Savin
    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
    Andrei Savin about 5 years
    Thank you for the explanation. A server-side proxy is a great suggestion.
  • John Carrell
    John Carrell over 4 years
    Not 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
    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
    Ivar almost 4 years
    @Sergey It has (AFAIK) always been allowed but in earlier versions of the specs it "SHOULD" be ignored.
  • Suamere
    Suamere over 3 years
    I 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 calling PUT or POST. (Not that you can't expect those to return data after their respective add/update action(s)).
  • Suamere
    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
    eisenpony about 2 years
    The 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
    eisenpony about 2 years
    Compare 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.