1

I'm trying to make a very basic node.js app using express, that takes browser event logs from log4javascript over CORS and HTTPS and that will write them to mongoDB. I'm stuck at trying to get the bodyParser to show the data. I've tried all sorts of bodyParser configurations, but req.body, req.params and req.query are always empty.

Here is my code.

var fs = require('fs'),
  bodyParser = require('body-parser'),
  express = require('express'),
  cors = require('cors'),
  app = express(),
  https = require('https'),
  key = fs.readFileSync('*****/key.pem'),
  cert = fs.readFileSync('*****/cert.pem'),
  https_options = {
    key: key,
    cert: cert
  };

app.use(bodyParser.json());
app.use(cors());
app.post('/', function (req, res) {
   console.log(req);
   res.send('Hello World!')
});

https.createServer(https_options, app).listen(3443);

I am using a JSON Layout in log4javascript. Here is my frontend code:

    var logger = log4javascript.getDefaultLogger(),                           
                 userAgent = navigator.userAgent.toLowerCase(),                        
                 ajaxAppender = new log4javascript.AjaxAppender("https://***/log/");
                 ajaxAppender.addHeader("Content-Type", "application/json");           
                 jsonLayout = new log4javascript.JsonLayout(false, false);             
                 ajaxAppender.setLayout(jsonLayout);                                   
                 ajaxAppender.setBatchSize(10);                                        
                 ajaxAppender.setThreshold(log4javascript.Level.INFO);                 
                 logger.addAppender(ajaxAppender);                          

and here is a sample of what log4javascript is sending according to Chrome:

Request Payload [{"logger":"[default]","timestamp":1421974733969,"level":"INFO","url":"https://*****/","message":["{\"message\":\"User clicked to hide a form\",\"form\":\"audio\",\"userAgent\":\"mozilla/5.0 (macintosh; intel mac os x 10_10_1) applewebkit/537.36 (khtml, like gecko) chrome/39.0.2171.95 safari/537.36\",\"browserTimestamp\":\"Fri, 23 Jan 2015 00:58:53 GMT\",\"browserUnixTime\":1421974733968,lds_display_name=barnaby_b%40testing.****.com\"}"]},{"logger":"[default]","timestamp":1421974734498,"level":"INFO","url":"https://*******.com/","message":["{\"message\":\"User clicked to expand a form\",\"form\":\"audio\",\"userAgent\":\"mozilla/5.0 (macintosh; intel mac os x 10_10_1) applewebkit/537.36 (khtml, like gecko) chrome/39.0.2171.95 safari/537.36\",\"browserTimestamp\":\"Fri, 23 Jan 2015 00:58:54 GMT\",\"browserUnixTime\":1421974734497,lds_display_name=barnaby_b%40testing.*****.com\"}"]}, .... etc.

What am I doing wrong? Does CORS, or HTTPS, or APACHE mod_proxy, or anything else interfere with Express's ability to parse the body? Does Log4Javascript send the POST in some strange way that I would need to configure for the body to be readable? Please help!

hendrixski
  • 1,124
  • 1
  • 12
  • 20
  • 2
    What does `console.log(req.headers['content-type'])` show? can you show the code you're using client-side to submit the request? – mscdex Jan 23 '15 at 01:33
  • I'm no node expert, but I can suggest a few things to check: 1. Before parsing happens, does the request even have a body? Is mod_proxy sending all the data it should? 2. If this is using CORS, you can expect a GET or HEAD preflight request to the same URL, which won't have any body. – Seán Hayes Jan 23 '15 at 02:34

1 Answers1

1

It depends how you've got the AjaxAppender set up. It can be configured to send log messages either as though posting a bunch of form fields (which is what it sounds as though you're expecting) or just send its payload unencoded (which is what seems to be happening). See the notes in the manual:

http://log4javascript.org/docs/manual.html#ajaxappender

Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Do you mean the choice of layouts? I had changed it from its default to JsonLayout. I've udpated my question to show the code. I tried removing that layout, and setting batch size to 1, but still, same issue. body, params, query, all are just {} when I inspect them in node.js – hendrixski Jan 23 '15 at 17:39
  • It's the `ajaxAppender.addHeader("Content-Type", "application/json");` that is switching the appender to sending its payload as raw JSON rather than URL-encoded form data. Drop that line and I think it will work as you want. – Tim Down Jan 23 '15 at 17:41