4

I've read node.js Extracting POST data.

But here's my problem, how to extract POST data with Express when I received a HTTP request looking like this?

POST /messages HTTP/1.1
Host: localhost:3000 
Connection: keep-alive
Content-Length: 9
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5 
Content-Type: application/xml 
Accept: */* 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4 Accept-Charset: UTF-8,*;q=0.5 

msg=hello

I can't seem to get the msg=hello key-value pair out of the body with Express.

I've tried all of these methods req.header() req.param() req.query() req.body but they seem to be empty.

How to get the body's content?

app.post('/messages', function (req, res) {
    req.??
});
Community
  • 1
  • 1
elliot
  • 51
  • 1
  • 4

5 Answers5

3

Your problem is bodyParser does not handle 'application/xml', I solved this mainly by reading this post: https://groups.google.com/forum/?fromgroups=#!topic/express-js/6zAebaDY6ug

You need to write your own parser, I've published the below with more detail to github:

https://github.com/brandid/express-xmlBodyParser

var utils = require('express/node_modules/connect/lib/utils', fs = require('fs'), xml2js = require('xml2js');

function xmlBodyParser(req, res, next) {
    if (req._body) return next();
    req.body = req.body || {};

    // ignore GET
    if ('GET' == req.method || 'HEAD' == req.method) return next();

    // check Content-Type
    if ('text/xml' != utils.mime(req)) return next();

    // flag as parsed
    req._body = true;

    // parse
    var buf = '';
    req.setEncoding('utf8');
    req.on('data', function(chunk){ buf += chunk });
    req.on('end', function(){  
        parser.parseString(buf, function(err, json) {
            if (err) {
                err.status = 400;
                next(err);
            } else {
                req.body = json;
                next();
            }
        });
    });
}

then use it with

app.use (xmlBodyParser);
arush_try.com
  • 440
  • 1
  • 5
  • 12
2

If you have this in the config:

app.use(express.bodyParser());

And this in your view:

form(name='test',method='post',action='/messages')
    input(name='msg')

Then this should work:

app.post('/messages', function (req, res) {
    console.log(req.body.msg);
    //if it's a parameter then this will work
    console.log(req.params.msg)
});
jabbermonkey
  • 1,680
  • 4
  • 19
  • 37
0

I believe you need to configure express to use the bodyParser middleware. app.use(express.bodyParser());

See the express documentation.

It says:

For example we can POST some json, and echo the json back using the bodyParser middleware which will parse json request bodies (as well as others), and place the result in req.body

req.body() should now return the expected post body.

I hope this helps!

Community
  • 1
  • 1
Norman Joyner
  • 955
  • 6
  • 12
  • Thanks! Yes, I have the `bodyParser` mounted, yet the `req.body` object is still empty :o – elliot Jun 13 '12 at 04:04
  • hmm interesting. are you sure you are sending a valid request body? have you tried submitting some json to the `/messages` path to test? – Norman Joyner Jun 13 '12 at 12:35
0

It's POSSIBLE (not sure what it depends on, but it happened to me once, it might be the bodyParser) that the request body is formatted in such a way that your JSON data is ITSELF being treated as a key in a key-value pair, with a blank corresponding value. What's worked for me in this situation was to extract the JSON object first and then proceed as normal:

var value;
for (var item in req.body)
{
    var jObject = JSON.parse(item);
    if (jObject.valueYouWant != undefined)
    {
        value = jObject.valueYouWant;
    }
}

This is probably pretty suboptimal, but if nothing else works (I tried for ages trying to find a better way and found none) this might work for you.

0

You are posting xml as I can see, the answers you got were based on JSON input. If you want the content of your xml displayed, process the raw request :

app.post('/processXml',function (req, res)
{
    var thebody = '';
    req.on('data' , function(chunk)
    {
        thebody += chunk;
    }).on('end', function()
    {
        console.log("body:", thebody);
    });
});

As an example using curl as your postman:

curl -d '<myxml prop1="white" prop2="red">this is great</myxml>' -H 
"Content-type: application/xml" -X POST 
http://localhost:3000/processXml

Outputting:

'<myxml prop1="white" prop2="red">this is great</myxml>'

Make sure your body-parser middleware doesn't get in the way: body-parser-xml processes your request object on the fly to a json object, after which you cannot process your raw request anymore. (And you can guess who was stuck several hours after this...)

Albert
  • 21
  • 5