68

The service API I am consuming has a given GET method that requires the data be sent in the body of the request.

The data required in the body is a list of id's separated by hypen and could potentially be very large and thus it must be sent in the body otherwise it will likely foobar somewhere in the browsers/proxies/webservers etc chain. Note I don't have control over the service or API so please don't make suggestions to change it.

I am using the following jQuery code however observing the request/response in fiddler I can see that the "data" I am sending is ALWAYS converted and appended to the query string despite me setting the "processData" option to false...

$.ajax({
   url: "htttp://api.com/entity/list($body)",
   type: "GET",
   data: "id1-id2-id3",
   contentType: "text/plain",
   dataType: "json",
   processData: false, // avoid the data being parsed to query string params
   success: onSuccess,
   error: onError
});

Anyone know how I can force the "data" value to be sent in the body of the request? Any assistance is appreciated, thanks in advance.

Oliver Pearmain
  • 17,376
  • 12
  • 77
  • 83
  • 1
    "in the body"? Only thing I can think of that's event _remotely_ close to what you're asking is a POST request... (`POST /path HTTP/1.0\r\n\r\n\r\n`) – Brad Christie Apr 24 '12 at 13:31
  • 3
    If the API is general, and adheres to the HTTP specifications, I don't think it will accept parameters sent in body of a GET request, even if you manage to do it. Are you sure about that? Useful post http://stackoverflow.com/questions/978061/http-get-with-request-body – Niks Apr 24 '12 at 13:46
  • Basically this just wasn't possible since as people have said it just isn't part of the HTTP spec. In the end we had to put the id's on the query string and page through the results so it didn't get too long. I will accept the answer thats been given, thanks EndangerredMassa. – Oliver Pearmain Jun 25 '12 at 11:24
  • 1
    Although not standard, there are cases when this is useful. When sending utf-8 encoded GET body, or to pass large json bodies. Elastic Search uses this style extensively. – sandstrom Apr 10 '14 at 18:02
  • Is sending a GET body less secure than sending a POST body? – user1637000 Feb 06 '21 at 19:00

3 Answers3

61

In general, that's not how systems use GET requests. So, it will be hard to get your libraries to play along. In fact, the spec says that "If the request method is a case-sensitive match for GET or HEAD act as if data is null." So, I think you are out of luck unless the browser you are using doesn't respect that part of the spec.

You can probably setup an endpoint on your own server for a POST ajax request, then redirect that in your server code to a GET request with a body.

If you aren't absolutely tied to GET requests with the body being the data, you have two options.

POST with data: This is probably what you want. If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests.

GET with query string data: You can convert your data to query string parameters and pass them along to the server that way.

url: 'somesite.com/models/thing?ids=1,2,3'
EndangeredMassa
  • 16,328
  • 8
  • 49
  • 79
  • 6
    Whilst I appreciate your input both suggestions involve changing the service which I've stated isn't possible. – Oliver Pearmain Apr 25 '12 at 08:49
  • Sorry, I missed that part. Updated with some more info, but it's not promising. – EndangeredMassa Apr 25 '12 at 14:48
  • 4
    Thanks for the additional suggestion of adding a Proxy that converts a POST to a GET with a body. I've attempted to implement this in .NET but it throws a "ProtocolViolationException" exception with error "Cannot send a content-body with this verb" clearly re-emphasizing that a GET with a body just isn't a support use case. – Oliver Pearmain May 11 '12 at 12:57
  • @EndangeredMassa Can't specify how many doubts of mine have you cleared with second half of your answer. I have first time realized when to use GET, POST and the parameters with the GET. Thank you! – Amit Tomar Dec 21 '15 at 13:26
  • 24
    Elasticsearch use GET with bodies extensively – Andrey Apr 21 '16 at 13:11
  • 1
    @EndangeredMassa, "If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests." is not true in the general case. The request could also pertain to be a search query, in which no model is modified and the server is performing a lookup with arguments supplied in the request. Those querying requests are often normal GET requests, for example in https://www.google.com/search?q=REST,HTTP,GET,query . – Jochem Schulenklopper Nov 10 '17 at 15:56
  • I don't even know why people insist that GET is something without the body data. Yeah, ofc, it makes more sense when you're trying to GET (I mean get logically) information using POST method with body (for example for filtering) just because someone said on the internet that you shouldn't pass body data in GET method. If you need to GET information and pass additional data (search query for example) - just go ahead and pass it. – Яктенс Тид Nov 03 '20 at 13:40
  • @Andrey thats true, however they also give you the option to use POST instead – Gellweiler Feb 14 '21 at 20:31
3

we all know generally that for sending the data according to the http standards we generally use POST request. But if you really want to use Get for sending the data in your scenario I would suggest you to use the query-string or query-parameters.

1.GET use of Query string as. {{url}}admin/recordings/some_id

here the some_id is mendatory parameter to send and can be used and req.params.some_id at server side.

2.GET use of query string as{{url}}admin/recordings?durationExact=34&isFavourite=true

here the durationExact ,isFavourite is optional strings to send and can be used and req.query.durationExact and req.query.isFavourite at server side.

3.GET Sending arrays {{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]

and you can access those array values at server side like this

let osValues = JSON.parse(req.query.os);
        if(osValues.length > 0)
        {
            for (let i=0; i<osValues.length; i++)
            {
                console.log(osValues[i])
                //do whatever you want to do here
            }
        }
-3

Just in case somebody ist still coming along this question:

There is a body query object in any request. You do not need to parse it yourself.

E.g. if you want to send an accessToken from a client with GET, you could do it like this:

const request = require('superagent');

request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
  if (err) throw new Error(err);
  console.log(res);
});

The server request object then looks like {request: { ... query: { accessToken: abcfed } ... } }

Neskews
  • 79
  • 1
  • 6
  • The OP is asking for `request.body`, not `request.query`. You mention `POST` but you still use `request.get()` in your code sample. – Danosaure Dec 19 '17 at 22:20
  • Yeah I see. But query and body can be used both get the same result. I figured it was very easy for him to consider request.query as an alternative. – Neskews Jan 22 '18 at 14:40
  • The user can see the request.query in his browser's address bar. Sometimes we want to hide from the user tha data that we transport. So, we still prefer POST requests – profimedica Jun 14 '18 at 23:49