Empty req.body receiving text/plain POST request to node.js - node.js

Why can't I receive plain text sent in a POST request body?
The request made from a client browser:
var xhr = new XMLHttpRequest();
xhr.open("POST", "/MyRoute/MySubRoute");
xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
xhr.send("hello!");
Using Express with my node server:
app.post('/MyRoute/MySubRoute', function(req, res) {
console.log("Received:"+require('util').inspect(req.body,{depth:null});
res.send();
});
Logged to the console I get:
Received:{}
I've tried with text/plain (no charset), with the same result. If I change my content type to application/json and pass a simple JSON string it works fine.

Summarising the above comments which answer the question:
The client's XMLHttpRequest is correct
On the server side, Express uses connect's bodyParser which by default only supports the following content types:
application/json
application/x-www-form-urlencoded
multipart/form-data
Because the content-type of text/plain is not implemented by Express, there is no method to wait for the body to be received before calling the app/post route.
The solution is to add the text/plain content type to Express as described here

Add
app.use(express.text())
You can read more about it here

Related

Formdata is passing null value in req.body nodejs

I am passing a uploaded file through formdata from client to server, and the request by the server received has empty body. Here is the code, can someone please help?
Client side code -
Server side code -
OUTPUT -
browser console -
nodejs console -
You need to use a middleware like multer to parse form-data
Your content-type will be
multipart/form-data
Not an application/json
Try to make something like this:
https://programmingwithmosh.com/javascript/react-file-upload-proper-server-side-nodejs-easy/

Express modifying the response headers

I'm using Express to to serve some webpages. I have a font file (woff) that I'm downloading using node's https API. I then pass the response headers along to the response I'm returning to the client. The issue I have is that express seems to be modifying the response headers, specifically the content-type and content-length headers.
I'm calling res.set() and passing the headers from the server side request
Here is some code:
app.get('/*', (req, res, next) => {
https.get(URI, (serversideRes) => {
serversideRes.on('end', () => {
res.set(serversideRes.headers);
console.log(res.getHeaders()['content-type']); //font/x-woff
console.log(res.getHeaders()['content-length']); //27756
res.send(data);
console.log(res.getHeaders()['content-type']); //font/x-woff; charset=utf-8
console.log(res.getHeaders()['content-length']); //49574
}
}
}
In the browser console I'm getting
Failed to decode downloaded font
OTS parsing error: incorrect file size in WOFF header
From the Express API
This method performs many useful tasks for simple non-streaming responses: For example, it automatically assigns the Content-Length HTTP response header field (unless previously defined) and provides automatic HEAD and HTTP cache freshness support.
In this case, the headers clearly seem to be previously defined.

nodejs- unable to fetch form data

I'm using Express JS (v 4.15.3) for building a node api.
I'm trying to fetch the values send from a form (via POSTman client). I'm not able to fetch it.
This is my form
with headers specified
Without headers
This is how I'm trying to fetch it:
router.post('/login',function(req, res, next) {
var email= req.body.email;
//var email= req.query.email; //also tried this
res.json({
value: email
});
});
I'm not getting error.
Note: I have included body parser.
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
Can anyone tell me why I am not getting the value? Thanks!
This is my first attempt at learning Node JS.
Your code seems perfectly alright. Though the issue is with the way you are sending request from POSTman client.
When you are sending request using use form data, POSTman sends this request as multipart/form-data, which actually sends your data in the format as below:
POST /api/login HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="email"
example#example.com
----WebKitFormBoundaryE19zNvXGzXaLvS5C
For multipart/form-data requests you need to use multer middleware, if you really need file-uploads with your application. But for your case you can just send data without using use form data (un-check the use form data checkbox), and setting content-type header as:
Content-Type: application/x-www-form-urlencoded
So after all these modifications your raw web request should look something like below:
POST /api/login HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
email=example#example.com
The POSTman screen capture for building the request and response is as below:
The POSTman screen capture for Raw request and response is as below:
Hope this will help you.
Try to set Content-Type to application/json and in body in raw write in json format like this :
{
"email":"example#gmail.com"
}
Here are the images which you can refer.
Don't forget to upvote the answer if you find it helpful.

Chrome is not rendering chunked json response

I want to make a streaming endpoint that keeps sending a json object. I have tried using chunked transfer encoding and was able to successfully make all the browsers (chrome, firefox, safari) render the data sent from the server if it was either text/html or text/plain. But when I use application/json as the content-type it does not work on chrome. Here's the code:
var http = require('http');
http.createServer(function(request, response){
response.setHeader('Connection', 'Transfer-Encoding');
response.setHeader('Transfer-Encoding', 'chunked');
response.setHeader('Cache-Control', 'no-cache');
// response.setHeader('Content-Type', 'application/json');
response.setHeader('Content-Type', 'text/html');
setInterval(function(){
response.write('test </br>');
// response.write('{"test": "test"}');
}, 10);
}).listen(8000);
The above code works as expected, but cant make it work with the application/json type. Am I missing something ?
This is a bug in browsers. and its fixed in latest chrome(at least in canary).
Chrome Bug - Transfer-Encoding chunked not support on text/plain
Safari (i have tested on Mac OSX) is the only browser that is not rendering the non-html content with chunked encoding.

how to support request or response bodies for application/json, application/x-www-form-urlencoded and multipart/form-data in nodejs

actually I am newbie, I want to use express in my web application, So I want support all the requests and response in my application should support
application/json, application/x-www-form-urlencoded and multipart/form-data
express is rather smart, and will automatically determine the header type, you can even use res.send(JSONObj) to send an object directly as JSON. If you want to manually set the header you can do so by using res.setHeader('Content-Type', 'application/json') before you send any data.

Resources