21

Having some trouble getting express to respond properly to my jquery ajax request. The actual posting is working fine, but no matter what I try I cant seem to actually get a data response from my app that I can use. At first it was just posting and hanging constantly, and like a minute later it would respond with an alert that said something like "XML Document loaded" (have no idea where it was coming from) -- Anyways, now its giving me

SyntaxError: Unexpected token ILLEGAL at parse (native) at IncomingMessage.

In my express App, I have:

    app.post('/save', function(req, res) {
      console.log(req.body.objectData);
      res.contentType('json');
      res.send({ some: 'json' });
    });

and in my jquery:

  $.ajax({
    url: "/save",
    type: "POST",
    dataType: "json",
    data: {objectData: someObject},
    contentType: "application/json",
    cache: false,
    timeout: 5000,
    complete: function() {
      //called when complete
      console.log('process complete');
    },

    success: function(data) {
      console.log(data);
      console.log('process sucess');
   },

    error: function() {
      console.log('process error');
    },
  });
Cœur
  • 37,241
  • 25
  • 195
  • 267
thrice801
  • 1,671
  • 5
  • 23
  • 31
  • 1
    The [tag:node] tag is not for node.js – Raynos Jun 09 '11 at 09:13
  • Can you open the chrome debugger inspector and look at the request body's JSON content? The error you are seeing is the server side JSON parsing choking on the JSON content in the request body. That is handled by express.bodyParser(). Maybe post the content of your request for folks to examine. You may also want to temporarily stop using express.bodyParser() so it's easier to manually debug your issue looking at the raw request body. – Peter Lyons Jun 10 '11 at 07:47
  • I am trying a similiar technique with this fix, but I can't get 'req.body.objectData to return anything but an error. Are you using another module or have any idea why this wouldn't work? – streetlight Feb 23 '13 at 15:42

3 Answers3

22

You are not sending a valid JSON response but a String containing the word json therefore the JSON.parse() is failing on the client side. Try this:

app.post('/save', function(req, res) {
  console.log(req.body.objectData);
  res.contentType('json');
  res.send({ some: JSON.stringify({response:'json'}) });
});

JavaScript Object Notation is a way to share data between applications in object format. However, you cannot send an object over an HTTP request without first turning it into a string and sending it as a single variable. The functions JSON.parse() and JSON.stringify() do this for us.

Aniket Kulkarni
  • 12,825
  • 9
  • 67
  • 90
Pastor Bones
  • 7,183
  • 3
  • 36
  • 56
  • This was useful. for me after I clicked submit I got the JSON on the page but no HTML. but when I used `stringify` I got the HTML and the data to my success function in AJAX. Thanks for your explanation. I didn't think it would help but I tried it and I seem to of got the expected results. – jack blank Jul 26 '16 at 04:22
2

Pastor Bones' comment was particularly important to me, as I was using $.ajax to post to a Node server. My relevant portion of code ended up like this:

// Incoming parameter "teams" is an array of objects
function saveTeams(teams) {
    var xhr;
    var data = JSON.stringify({ teams: teams });

    xhr = $.ajax({
        type: "POST",
        url: "http://localhost:8000/saveteam",
        contentType: "application/json",
        data: data,
        headers: {
            Authorization: "..."
        }
    });

    return xhr;
} 

Note that the contentType header is relevant for the parsing to work.

On the node server side, I can process the payload like this:

saveTeams: function (req, res, next) {
    var teams = req.body.teams;

    if (teams.length > 0) {
        console.log("Teams to be added:");
        for (var i = 0; i < teams.length; i++) {
            console.log(teams[i]);
            // ...
        }
    }
    // ...
}
CLO
  • 21
  • 3
1

Since you are using express,

res.contentType('json');

should be:

res.type('json');

but setting the type is not required since it is done automatically for you.

See the express api docs on res.type.

Also note that, for express, res.send({blah:"gee"}); automatically converts json objects using JSON.stringify internally. After clicking the above link, click on res.send and, while you are at it, res.json which saves a little processor overhead when you know you are sending JSON. Note that if you send JSON, the type is automatically set to JSON.

Always best to look at the source! Note that res.send calls this.json when it detects JSON, and that res.json calls this.send (yeah seems like a loop but it all works out).

Montana123
  • 11
  • 3