How do I retrieve the object I passed in jQuery.ajax()'s `data` attribute on the server side (node.js)?

I made a chrome extension which calls jQuery's ajax method:

content-script.js

[...]
$.ajax({
    "url": "http://localhost:5000/",
    "type": "PUT",
    "contentType": "application/json",
    "data": { "name": "random object" },
    "dataType": "json"
});
[...]

On the server side, I'm trying to fetch the information passed in the data attribute:

web.js

[...]
app.put('/', function(request, response) {
    console.log(request.data);
});
[...]

But I'm getting undefined instead. How is the object passed in the data attribute supposed to be retrieved on the server side (Node.js + express.js)?

I also tried console.log(request) and got a LOT of stuff in there, but nothing that looked like the info I passed along in the data attribute...

EDIT

My latest attempt (based on graydsl's answer) brings the following changes to the code above:

  • Added app.use(express.bodyParser()); just before app.put....
  • Changed put to post everywhere
  • Changed request.data to request.body.data

Now, the code does what I want when responding to a form like this:

<form method="post" action="/">
    <input name="data" type="text" value="WOO HA" />
    <input type="submit" name="submit" value="submit" />
</form>

However it still fails if I revert to using post instead of put (and the browser ends up on http://localhost:5000/?data=WOO+HA&submit=submit for some reason)

It also fails when putting (or posting) with ajax (see code above). When I try it with ajax, I get this on the server:

SyntaxError: Unexpected token ILLEGAL
    at Object.parse (native)
    at IncomingMessage.<anonymous> (/home/shawn/.node_libraries/.npm/connect/1.8.7/package/lib/middleware/bodyParser.js:135:16)
    at IncomingMessage.emit (events.js:61:17)
    at HTTPParser.onMessageComplete (http.js:133:23)
    at Socket.ondata (http.js:1019:22)
    at Socket._onReadable (net.js:683:27)
    at IOWatcher.onReadable [as callback] (net.js:177:10)

  1. As others have mentioned, and you're now doing, you need to use the bodyParser` middleware.

  2. If the request body has a content type of "application/json", bodyParser will parse it into an object, which will be located at request.body. Thus in your case request.body.name should be "random object".

I think you (and several of the previous responders) are mentally hanging up on the fact that jQuery's ajax method uses the key name "data" for an object to be sent (serialized as JSON) in the request body, and magically sliding to the assumption that anything on the server side that processes the request will also call that object by the name of "data". There's no connection between the two.

You have to use req.body.data. Something like this should work:

app.post('/', function(req, res) {
  console.log(req.body.data);
  res.redirect('/');
});

Take a look at this link: bodyParser

I hope I could help you! :)

EDIT: Just found a nice lib for working with $.ajax, it's called: superagent. You might consider giving it a try. Looks promising. :)

Update

The problem lies in your jquery code not in the node.js code. You can't send an object in the data property of the settings object, you have to stringify the data object first. You can use the json2.js from the awesome D - to the - ouglas Crockford: json2.js

After you included that library the following code should give you the result you want:

$().ready(function() {

    var data = {
        data: "My name is",
        name: "Slim Shady"
    };

    stringifiedData = JSON.stringify(data);

    $.ajax({
        "url": "http://127.0.0.1:3000/",
        "type": "PUT",
        "contentType": "application/json",
        "data": stringifiedData,
        "dataType": "json"
    });
});

And in the app.js:

app.put('/', function(req, res) {
    console.log(req.body.data + "... " + req.body.name);
    res.redirect('/');
});

The jquery data attribute gets translated into a query string or post data before being sent to server. To retrieve it, use node.js to decode GET and POST parameters.

You said you use express.js. In express.js, if you pass data like this: { EmployeeName : "George" } then, in express.js, request.params.EmployeeName will contain "George".