Reputation: 151
On the webpage I am POSTing some JSON using jQuery:
$.post('/url', data);
My data is a javascript object that contains some values and an array. JSON.stringify(data)
looks like:
{"favoriteAnimal":"piglet", "okayAnimals":["cats","dogs"]}
I'm consuming this JSON in a NodeJS webapp using ExpressJS (which is wired up with the body-parser middleware). I can retrieve the favorite animal like req.body.favoriteAnimal
and it gives me the string piglet
which is all fine and dandy.
But how do I access the values in the array?
req.body.favoriteAnimal // piglet
req.body.okayAnimals // undefined
req.body.okayAnimals[] // syntax error
This works...
req.body['okayAnimals[]']
...but smells fishy. It also won't return an array if the original data that is being POSTed contains only one element in its array (it just returns a single string).
Is there something going on with the the jQuery encoding of the JSON or something going on with the decoding in ExpressJS that's preventing me from accessing it like req.body.okayAnimals
and getting an array every time?
Upvotes: 3
Views: 5275
Reputation: 151
Kevin's answer almost got me there.
$.post('/url', JSON.stringify(data))
will send a string which is one step closer. Unfortunately jQuery's $.post
sets the wrong header
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
which ExpressJS's body-parser will not handle appropriately. You end up with
req.body={"{\"favoriteAnimal\":\"piglet\",\"okayAnimals\":[\"cats\",\"dogs\"]}":""}
I rewrote how I was sending the data.
$.ajax({
url: '/url',
type: 'POST',
data: data,
contentType: 'application/json; charset=utf-8',
dataType: 'json'
})
I saw that my browser was sending the correct headers
Content-Type:application/json; charset=UTF-8
And observed
req.body={"favoriteAnimal":"piglet","okayAnimals":["cats","dogs"]}
Upvotes: 1
Reputation: 95064
JavaScript objects and JSON are two very differen things, which is the root of the problem you are seeing. What you are passing to $.post()
is actually an object, not json, and is therefore being converted to a paramstring by jQuery before being sent to node. In this case, the paramstring is:
favoriteAnimal=piglet&okayAnimals[]=cats&okayAnimals[]=dogs
which of course explains why an okAnimals[]
property exists on the body.
I'm surprised that the middleware you are using to parse the body isn't picking that up properly, but regardless you should instead pass a json string to $.post
if you want to send it as is.
$.post('/url', JSON.stringify(data));
Upvotes: 1