105

How can I make an AJAX POST request sending JSON data using vanilla JS.

I understand the content-type is url form encoded and it doesn't support nested JSONs.

Is there any way I can make such a POST request using nested JSON in plain old JS. I've tried the various serialize methods found here on SO but they all flatten my JSON into one format.

Here's my JSON:

{
   email: "hello@user.com",
   response: {
       name: "Tester"
   }
}
Gilles Quenot
  • 143,367
  • 32
  • 199
  • 195
Akshay Khetrapal
  • 2,130
  • 4
  • 18
  • 35
  • 1
    Your question does not contain valid JSON. Perhaps you are sending this JavaScript object, which is then converted to JSON through some process? Either way, as has been said by others in the comments to the below answer, there isn't any reason why your JSON object should be flattened. If you are having issues with a specific library or block of code, post that instead. – Ray Nicholus Sep 15 '16 at 20:06

1 Answers1

275

If you use JSON properly, you can have nested object without any issue :

var xmlhttp = new XMLHttpRequest();   // new HttpRequest instance 
var theUrl = "/json-handler";
xmlhttp.open("POST", theUrl);
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xmlhttp.send(JSON.stringify({ "email": "hello@user.com", "response": { "name": "Tester" } }));
John
  • 27,040
  • 17
  • 82
  • 121
Gilles Quenot
  • 143,367
  • 32
  • 199
  • 195
  • 1
    You did not specify the target URL in `open()` ? – Billal Begueradj Aug 14 '18 at 04:27
  • 4
    not working for me :( – markroxor Sep 02 '18 at 11:53
  • 1
    @BillalBegueradj, his target URL is "/json-handler", a relative path to the domain where the call is being made. May be the name is a bit confusing, it happened the same to me... Just change it for "someFolderNameHere" – Arampg Nov 19 '18 at 17:23
  • Not working for me either. @markroxor did you sort this out? – mike_butak Jan 30 '19 at 21:36
  • 2
    Note that this only works for "POST" and "PUT" requests. If you are using a "GET" request, the argument to of xmlhttp.send([argument]) will be ignored. I wound up changing an AWS API Gateway endpoint resource to "PUT" to get around this issue... – James Shapiro Mar 04 '19 at 18:25
  • CORS won't allow URLs without http(s):// before them. Another thing stopping this is the CORS policy with Content-Type='application/json' . . . This will force a pre-flight XHR test with POST changed to OPTIONS. This request may hang . . . – Trunk May 14 '19 at 12:40
  • @JamesShapiro See https://stackoverflow.com/questions/978061/http-get-with-request-body as to why xmlhttp doesn't send it. xmlhttp will ignore it under the presumption that all servers follow the http desired specification and ignore it as well, so xmlhttp thinks its accomplishing the same thing with fewer bytes sent – Nicholas Pipitone Aug 01 '19 at 02:21
  • 1
    `charset=UTF-8` is unnecessary because it is the default encoding/charset for the application/json type – Ivanzinho Aug 09 '19 at 16:05
  • 1
    This doesn't seem to actually send the post body for me... – Tyguy7 Nov 14 '19 at 16:48
  • Very good example! – Sherzod Jan 31 '20 at 10:21
  • If your endpoint URL is a directory, try adding a "/" at the end of the URL - Chrome was neglecting to send data until I did this (due to header/CORS validation failing) – 1owk3y Mar 16 '20 at 13:12