Express: bodyParser fails to handle literal string that is JSON coded

Created on 19 Aug 2013  路  13Comments  路  Source: expressjs/express

A properly encoded string in JSON format does not work:

curl -d '"MyString"' -H "Content-Type: application/json" http://localhost:4000
Error: invalid json
    at Object.exports.error (/node_modules/express/node_modules/connect/lib/utils.js:60:13)
    at IncomingMessage.<anonymous> (/node_modules/express/node_modules/connect/lib/middleware/json.js:74:71)
    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at _stream_readable.js:883:14
    at process._tickCallback (node.js:415:13)
3.x body-parser question

Most helpful comment

RTFM. Sorry.

Looks like the above can be fixed with:

app.bodyParser({strict:false});

which allows the connect middleware to parse anything JSON.parse() will handle. Not sure why thats not the default.

All 13 comments

RTFM. Sorry.

Looks like the above can be fixed with:

app.bodyParser({strict:false});

which allows the connect middleware to parse anything JSON.parse() will handle. Not sure why thats not the default.

2.  JSON Grammar

   A JSON text is a sequence of tokens.  The set of tokens includes six
   structural characters, strings, numbers, and three literal names.

   A JSON text is a serialized object or array.

      JSON-text = object / array

^-- that's why, the recursive nature of JSON.parse is why it accepts primitives, but that's somewhat of a bug

Those two statements conflict.

Note that the first says a JSON text is a sequence of tokens. As "a sequence" means 0 or more, and a single string is 0 or more tokens, it says a single string is a JSON-text. The second, disagrees.

Interestingly, wikipedia agrees with the fully recursive definition: http://en.wikipedia.org/wiki/JSON#Data_types.2C_syntax_and_example

As does JSON.serialize()

JSON.stringify("string");

---> '"string"'

I am still left wondering why the more robust interpretation is not the default. Is there some benefit to being so pedantic?

FWIW, json.org also disagrees: http://www.json.org/fatfree.html

the main reason is because it's very common to expect req.body to be an object so if you start doing things like this on primitives suddenly you have a lot more checks to make:

if (req.body.foo) {

I'd definitely consider sending of primitives to be the less common use-case

I don't buy that argument at all. Someone is just as likely to assume structure down the line:

if (req.body.foo.bar){...}

What if just {"foo":"string"} is sent? Same problem, just recursed down a level.

well you're welcome to fork the project and change the default, that's the default I prefer

why not wrap the string you're sending with an object so it has context anyway, or use a different encoding if it's just a string, like text/plain :p

Forking just results in a "tower of Babel" problem. Its not that important as there's a workaround. As for the question above, its because my client and server have a notion of being able to send any valid data back and forth.

With the relaxed definition of JSON, that works well.

It seems wasteful to always send {"data" : mydata}, and then using req.body.data instead of just sending mydata and using req.body

As you point out, its your project and your prerogative. Just not sure whats to be gained.

extra checks for the average use-case, that's what is gained, I would rather support that by default than supporting the less likely case of passing around primitives

I'm clearly not going to convince you. But I'm at a loss why not having to check if ("foo" in req.body) is somehow any different (or any savings) from having to check if ("bar" in req.body.foo)

I just know of no other software that makes that distinction. So I suppose my objection is simply because of the fact that the behavior is unusual and unexpected.

Anyway, thanks for providing some really great software!

i would hate doing if ("object" == typeof req.body), when i need strings i simply send an array ["foo"] then i would get it easily with req.body[0].

if node caught errors properly like everything else we wouldn't have to make that kind of 'optimization', but that's not the case

Was this page helpful?
0 / 5 - 0 ratings

Related issues

prashantLio picture prashantLio  路  3Comments

zackarychapple picture zackarychapple  路  3Comments

cuni0716 picture cuni0716  路  3Comments

HafidAbnaou picture HafidAbnaou  路  3Comments

afanasy picture afanasy  路  3Comments