Search code examples
javascriptnode.jsexpresspostxmlhttprequest

Post request body empty - XMLHttpRequest to Express server


I am trying to access a body from a post request sent using XMLHttpRequest to an express server. However the body of the request is empty and I cannot seem to understand why that is.

I have included a body-parser in the express app, and I have tried to replicate some code from SO answers. But I still get it wrong somehow.

<script>
    const Http = new XMLHttpRequest();
    Http.open('post', 'localhost:3000');
    Http.send("sending something!");// this resolves to {} on the backend?
    Http.onload = function() {
     alert(Http.response); 
    };
</script>

This is how I try to handle it on my express server

const express = require("express");
let app = express()
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
    extended: true
}));
app.post("/post", (req, res) => {
    console.log("inside of post");
    console.log(req.body);
})

app.listen(3000)

This is the logs

inside of post
{}

I expect the console.log() to print "sending something!" that I try to send with the request with Http.send("sending something!");.


Solution

  • You have specified the body-parser to parse the body as url-encoded format which would work if you pass data like this:

    Http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    Http.send("param1=value1&param2=value2");
    
    /* console output:
    { param1: 'value1', param2: 'value2' }
    */
    

    In your case, the data being passed is simple string, which the backend interprets as empty JSON {} as it is unable to parse.

    For it to work try setting the format of data as follows

    <script>
        const Http = new XMLHttpRequest();
        Http.open('post', 'localhost:3000');
        Http.setRequestHeader("Content-Type", "text/plain");
        Http.send("sending something!");
        Http.onload = function() {
         alert(Http.response); 
        };
    </script>
    

    And in express server:

    const express = require("express");
    let app = express();
    const bodyParser = require("body-parser");
    // app.use(
    //   bodyParser.urlencoded({
    //     extended: true
    //   })
    // );
    
    app.use(bodyParser.text({ type: "text/plain" })); // use this instead
    
    app.post("/post", (req, res) => {
      console.log("inside of post");
      console.log(req.body);
      return req.body;
    });
    
    app.listen(3000);
    

    Then you might be able to read the message "sending something!" in the backend. Just make sure you are setting the right contentType header in XMLHttpRequest while sending and you use same type while parsing in the backend as well.

    For more info on bodyParsers refer this doc