When sending a POST request, when should I JSON.stringify() it or not?

Viewed 9248

While looking at tutorials and code examples from different places, I noticed that sometimes in a code the JSON object sent through the "data" header in a HTTP request is processed with JSON.stringify(data) before being sent, and sometimes they send it without being "stringified" first.

Using examples from .NET WEB API tutorials, client-side code:

var data = {
    Email: self.registerEmail(),
    Password: self.registerPassword(),
    ConfirmPassword: self.registerPassword2()
};

$.ajax({
    type: 'POST',
    url: '/api/Account/Register',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(data)
}).done(function (data) {
    self.result("Done!");
}).fail(showError);

In this example, if I understand correctly this will convert data into something like: {"Email":"alice@example.com","Password":"Password1!","ConfirmPassword":"Password1!"}

But in this part from the same client-side code:

var loginData = {
    grant_type: 'password',
    username: self.loginEmail(),
    password: self.loginPassword()
};

$.ajax({
    type: 'POST',
    url: '/Token',
    data: loginData
}).done(function (data) {
    self.user(data.userName);
    // Cache the access token in session storage.
    sessionStorage.setItem(tokenKey, data.access_token);
}).fail(showError);

JSON.stringify() isn't used. What would be the difference? If I'm understanding correctly, HTTP requests are text-based and therefore I used to stringify all my requests.

EDIT:

These are the data-bound elements with KnockoutJS:

//...Other HTML markups...

<input class="form-control" type="text" data-bind="value: registerEmail"/>
//...Other HTML markups...

<input class="form-control" type="password" data-bind="value: registerPassword"/>
//...Other HTML markups...

<input class="form-control" type="password" data-bind="value: registerPassword2" />
//...Other HTML markups...

<input class="form-control" type="text" data-bind="value: loginEmail"/>
//...Other HTML markups...

<input class="form-control" type="password" data-bind="value: loginPassword"/>
2 Answers

If the object you are sending through the post request doesn't have nested Objects it's safe to send data without converting it to string.

Otherwise, if your payload (data) is something like this:

var data={
  Email:"username",
  Password:"password",
  extraOptions:{
    option1: { Verified:true },
    option2: { empty:false } 
  }
};

Then "JSON.stringify()" it. Or your request body JSON will look like this.

{ 
  Email:"username",
  Password:"password",
  extraOptions[option1][Verified]:true,
  extraOptions[option2][empty]:false
} 

And send data as:

$.ajax({
    type: 'POST',
    url: '/api/Account/Register',
    contentType: 'application/json; charset=utf-8',
    data: {data:JSON.stringify(data)}
}).done(function (data) {
    self.result("Done!");
}).fail(showError);

So in your backend "req.body.data" is your string.

var json=JSON.parse(req.body.data)

Both way you can send data to backend. If you send in string data, you need to parse in backend. Even if you send data like Array, or Object, you can directly assign to any variable.

Related