Express not receiving POST content - node.js

Need some help debugging the following situation. I am using some javascript code that sends data to a server using XMLHttpRequest()
It ends with req.send of this string "{ "xxxxsortBy": "xxxxxcoolness", "take": 10 }". (This is from the Elm Http.post method in practise.)
I'm running express with
app.use(bodyParser.json({limit: '10mb'}));
app.use(bodyParser.urlencoded({limit: '10mb', extended: true}));
Curl commands seem to work as do some other Post commands from older code, but when I log out req.body all I get is {}.
I would welcome some help trying to debug this situation - i.e. to get req.body to include the content posted. (e.g. curl --data "data=this is a text" http://localhost:5000/tcx does get picked up properly)
Below is part of the req that I receive on the server side.

Related

Body parsers behaving weirdly

I am trying to develop an app with few APIs, the issue I am facing here is when I use
app.use(bodyParser.urlencoded({ extended: false }));
as my middleware, it doesnt intake the requests i send through postman (all the request sent through postman goes with empty body idk why. And it takes all the requests sent via html form.
On the other hand, if I use
app.use(express.json({extended: false}))
as my middleware to parse json objects, it takes all the requests from postman but doesnt take requests from my browser form. Can anyone explain whats happening here?
In order for express to be able to parse both JSON request payloads and simple form-data requests, you simply need to setup both of the mentioned middlewares (note that express.json() does not have an extended option):
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.json());
See the docs for more information:
https://expressjs.com/en/api.html#express.json
https://expressjs.com/en/api.html#express.urlencoded

Request Entity Too Large

My Express application is returning "Request Entity Too Large" on a file upload of only a 125kb PNG file.
I have configured the body parser middleware as such:
app.use(bodyParser.urlencoded({
limit: '5mb',
type:'*/x-www-form-urlencoded',
extended: true
}));
according to the documentation. No matter how high I set the limit, or what combination of options, I always get the same result. I am using Express 4.13.3 and body-parser 1.15.2.
What am I doing wrong?
Embarrassingly, I had accidentally pointed my route handler to the wrong Express Router instance. Once I was pointed to the correct handler, Multer picked up the multi-part POST correctly.
Interestingly, when testing with Postman, it will send an array of files, even if you only select one, which is why request.file was undefined, but request.files contained the correct value.

node.js server: HTTP POST body is empty

I am sending info from a wi-fi connected arduino device (cc3000) to an AWS server running express/node. I plan to eventually hook the endpoint up to SQS as a producer, but for now I am just trying to get a POST request to work. The problem is, I am on secure shell on my AWS and the body portion is empty as I see post requests stream in. However, the headers are present as I have sent them. My question is, where is the data going? Is this a formatting problem or something wrong with AWS?
Raw body of POST request (I am just using plain/text for now to see if I can get this to work):
POST /postdata/ HTTP/1.1
Host: *******************
User-Agent: Arduino/0.6.0
Accept: plain/text
Content-Length: 36
Content-Type: plain/text
{"temperature_c": "29.80"}
Again, the headers are in the JSON payload, but not the "temperature" portion.
Here is the endpoint:
app.post('/postdata', function (req, res) {
Sensor_data.create(req.body);
console.log(req.body);
});
The headers are present. This is intended to write to a mongoDB. If I do a cURL request from the command line, it writes successfully. For example, this works:
curl -v *************** -d "{temp_f=28.40&relative_humidity=45.40"
So if the headers are there, I know I am successfully writing something to the server. Where the heck is the data? Is this a formatting problem or something wrong with AWS?
## EDIT ########:
I double checked to make sure body-parser was set up. I had installed the middleware in my server.js as so:
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
However, another issue has arisen. I have some code in this route to help me see what is going on by logging to console. I changed the POST request to application/json and know it is parsing because I had a small typo that I had to fix. However, once it started parsing correctly, nothing logged to console and nothing wrote to mongoDB. Any idea what is happening there? If the JSON is in fact being parsed, where is it being received on the server?
This issue was solved by setting app.use(bodyParser.urlencoded({ extended: false })); to be initialized with true and creating the post request with Accept and Content-Type to application/x-www-form-urlencoded. Hope this post helps some people as I have have seen quite a few posts with people struggling with this issue
It isn't clear whether you've set up the appropriate middleware to do the parsing. You'll find documentation here - in the first example you'd need the json parser, and in the second you'd need urlencoded (although there appears to be an extra leading { - a typo, perhaps?).
I am just using plain/text for now to see if I can get this to work
That's not going to work. The json-parsing middleware decides whether to try to parse based on the content-type - if you aren't honest, it doesn't know it should try to parse. Use application/json if you're going to send a JSON body.

Making a proxy with request and express in node

I'm trying to make a proxy with the express and request module. This post shows how to easily pipe() the request to the response:
app.use(express.json()); // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies
//app.use(express.multipart());
app.use('/api', function(req, res) {
var url =proxyUrl + req.url;
req.pipe(request(url)).pipe(res);
});
It works very well for all GET request. But on a POST request it fails. Can't figure out what is happening because it only runs into a timeout. The POST request works on the proxy.
What am I doing wrong? Is there any changes that I can debug the request? I have tried the following, but the file is empty:
req.pipe(fs.createWriteStream("test.txt"));
We are also experiencing same issues, its because express.json(). After disabling json parser, it work ok. But that not the idle solution as you might need json parser.

How does one retrieve the entity body from a request in Node.js/Express (for CSP violation reporting)?

I am interested in implementing a Content Security Policy (CSP) for my Node.js application. Mozilla's docs are rather helpful but I am stuck at how to enable violation reports. I understand the basic premise of how they work (the browser sends a POST request to the specified URL to notify the website of a violation) but could not figure out where to find the JSON document describing the violation in the HTTP request. Perhaps this would have been obvious to someone more familiar with the HTTP spec.
Looking at the W3C draft for CSP, I established that the JSON is contained in a portion of the HTTP called the "entity body". I still don't know what the purpose of the entity is (the only mildly useful page I could find on the matter was one from the HTTP spec). I am assuming it the body of the request.
Perhaps more importantly, I cannot find any way to retrieve the contents of the entity body. I thought of using req.header('entity-body') but that doesn't work as the entity is not a HTTP header. What is it and how to I fetch it?
(Additionally, I tried finding a tutorial on how to implement CSP violation reporting in Node.js and found nothing. I did find one for PHP but it wasn't particularly helpful, referencing a file_get_contents('php://input') which I don't have anything similar to in Node.js/Express.)
Any assistance would be greatly appreciated.
It turns out I was over-analyzing things. All you need to do is enable the express.bodyParser() middleware for express and then fetch req.body in the POST event handler. This retrieves the body of the HTTP request containing the JSON violation report.
Enable middleware:
var server = express.createServer(
// other middleware here
express.bodyParser()
);
Retrieving violation report:
server.post('/csp/', function(req, res) {
console.log(req.body);
});
I went through some difficulties getting my Express app fronted with Nginx to report csp violations and the two things I learned from the above answer were:
Should be POST method and not GET method
req.body contains the report
But, the above was not sufficient and I kept getting empty req.body and I could not find any other post to describe how to fix it. After some research I came across this post as well as a totally isolated github issue where dougwilson give hints where to put the route that handles the csp report.
The reason the req.body was empty for me was because I placed the csp report route handler after the following configs:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
I moved the csp report route handler above these but, I still kept getting empty req.body then I added the following above csp report route handler to get the report in req.body
app.use(bodyParser.json({ type: 'application/csp-report' }));
After adding the above line above csp report request handler, Express understood that it should parse requests that have Content-type as application/csp-report.
Maybe Express by default do not parse application/csp-report, and adding the above resolved the issue for me. I also googled if Express parses application/csp-report by default and I came across this gist claiming that Chrome sends application/csp-report whereas Firefox sends application/json (and I am using Chrome - you can include application/json also if you face issues with FF).
So this is how it looks in my app.js
// without following csp-report don't get parsed.
app.use(bodyParser.json({ type: 'application/csp-report' }));
app.get('/vehicle/cspreport', function(req, res) {
res.status(403);
});
app.post('/vehicle/cspreport', function(req, res) {
console.log('csp report > ' + JSON.stringify(req.body));
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
...
The accepted answer posted by OP is from 2011 and I thought of adding an answer to show how I resolved this issue in 2016 with the following versions of Node.js, Express and Nginx
Node: v4.2.4
Express: 4.13.1
Nginx: 1.8.1

Resources