4

While writing an API, I have come across a very thorny error: when I try to do a res.send(INSERT JSON) with a Content-Type header application/json (a default for most AJAX), I get an invalid json error. When I set the content-type to anything else (eg. text/plain), I get the correct response, but in order to use some front-end frameworks, I need to support application/json. Here is the actual error message:

Error: invalid json
    at Object.exports.error (/Users/Brad/node_modules/express/node_modules/connect/lib/utils.js:44:13)
    at IncomingMessage.module.exports (/Users/Brad/node_modules/express/node_modules/connect/lib/middleware/json.js:68:73)
    at IncomingMessage.EventEmitter.emit (events.js:85:17)
    at IncomingMessage._emitEnd (http.js:366:10)
    at HTTPParser.parserOnMessageComplete [as onMessageComplete] (http.js:149:23)
    at Socket.socket.ondata (http.js:1680:22)
    at TCP.onread (net.js:410:27)

My server code is below:

app.configure(function () {
  app.use(express.bodyParser());
  app.use(express.cookieParser('SALT'));
  app.use(express.static(__dirname + '/static/'));
  app.use(express.session());
});

app.get('/users', function(req, res) {
  res.send({'test': 'test'});
});

Here is an picture of my Postman setup--I am using the Postman Chrome extension to test my API: enter image description here

Brad Ross
  • 451
  • 8
  • 26
  • 1
    That code looks just fine, and works fine too. What is generating the 'invalid json' error? – robertklep Jun 02 '13 at 06:33
  • When I make a GET Request with `content-type` as `application/json`, I get the invalid JSON error. I'll ad the actual error to my question. – Brad Ross Jun 02 '13 at 13:35
  • 1
    I think that means the data you are sending *to the server* isn't valid JSON. How are you testing this (which client)? – robertklep Jun 02 '13 at 15:56
  • I am using the Postman extension on Chrome. I'm simply typing in the url (localhost:3000/users), setting it to make a GET request, and typing a header. – Brad Ross Jun 02 '13 at 16:07
  • I installed Postman and did the same, running the server code you posted, and it works just fine. – robertklep Jun 02 '13 at 18:18
  • Check out my update above for a picture of how I did my postman setup. – Brad Ross Jun 02 '13 at 19:44

1 Answers1

4

I believe the problem is that you want to be using Content-Type header in your servers response; not in your request Content-Type header.

When you use the Content-Type header in your request, Express will read the Content-Type and attempt to interpret the provided information as that Content-Type, in this case, as JSON. Because this is a GET request and thus has no body, Express is trying to interpret an empty string as JSON, which is giving you the error.

Nick Mitchinson
  • 5,452
  • 1
  • 25
  • 31
  • 2
    Yes, for a `GET` the server would expect an `Accepts` header that would be set with the same value (`application/json`). – Davin Tryon Jun 02 '13 at 19:56
  • Thanks for the `Accept` suggestion--that works really well in Postman. However, I am trying to connect this API to ember.js's RESTAdapter, which still gives the same error when it makes the GET request to the server. – Brad Ross Jun 02 '13 at 20:20
  • The Accepts header is more the request letting the server know what the client is expecting. There is no guarantee that the server will actually return this. – Nick Mitchinson Jun 02 '13 at 20:43
  • Rather strange that I couldn't reproduce the issue with Postman, but good to see it's solved :) – robertklep Jun 03 '13 at 07:17
  • @robertklep you can reproduce the issue with Postman by setting a Content-Type: application/json header and making a GET request to any Express server running. I believe that the bodyParser middleware has to be in use. The same issue can also be seen by sending a POST request with Content-Type: application/json and an empty body; but can easily be correctly by sending a body of '{}'. – Nick Mitchinson Jun 03 '13 at 13:34
  • @NickMitchinson that's how I tested, and it works just fine (Express@3.2.6, [gist](https://gist.github.com/robertklep/5698251), [screenshot](https://dl.dropboxusercontent.com/u/1577733/demo.png)). – robertklep Jun 03 '13 at 13:49