Home > Enterprise >  Why is req.body an empty object?
Why is req.body an empty object?

Time:01-07

I'm trying to learn XMLHttpRequests. I'm trying to send some input to the server, but when it gets there, the Object is empty, like {} That setRequestHeader I commented out, if it's in, the object gets printed out properly, but I get an error that it should be open on the browser. BUT if I put it after the open() statement, it stops working again and the object arrives empty. I also have tried all of that and also JSON.stringfy the variable before sending it but it also didn't work.

//server.js
const express = require('express');
const app = express();
const cors =require('cors')

app.use(cors())

app.use(express.urlencoded({extended:true}))

app.post('/frases', function(req, res) {
    console.log(req.body);
    const frase = new phrase(req.body);
    // console.log(frase);
})

app.listen(3000, () => console.log('listening on 3000...'));

//script.js
var form = document.getElementsByTagName('form')[0];

const xhr = new XMLHttpRequest();
// xhr.setRequestHeader('Content-Type', 'application/json');

form.onsubmit = (e) => {
    e.preventDefault();
    const thisName = form.elements[0].name;
    const thisValue = form.elements[0].value;
   
    const frase = {[thisName]:thisValue};
    console.log(frase)
    xhr.open('POST', 'http://localhost:3000/frases');
    xhr.send(frase);

    }; 


<!-- index.html -->
    <form action = "http://localhost:3000/frases" method="post">
        <label for="frasefavorita"> Qual é a sua frase favorita?
            <input id= 'frase' type="text" name="frasefavorita">
            <button id= 'send-frase' type="submit">Enviar</button>
    </form>

CodePudding user response:

req.body is empty by default because the body of the incoming request is not read by default. You need middleware that matches the incoming content-type in order to read that body, parse it and put the results into req.body.

And, in your xhr call, you have to decide what content-type you're going to use to send the data, have to put the data into that content-type and you have to set that header appropriately. Then, you will be able to add the right middleware to your server to read and parse that body and then, and only then, can you access it in req.body on your server.

If you were going to send it as JSON, then you can do this on the client to set the content-type for JSON and to format the data as JSON:

form.onsubmit = (e) => {
    e.preventDefault();
    const thisName = form.elements[0].name;
    const thisValue = form.elements[0].value;
   
    const frase = {[thisName]:thisValue};
    const xhr = new XMLHttpRequest();
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.open('POST', 'http://localhost:3000/frases');
    xhr.send(JSON.stringify(frase));

}; 

Then, on your server, you can add this middleware before your /frases route handler:

// read and parse incoming JSON request bodies
app.use(express.json());

That will read and parse the application/json content-type data coming from your Ajax call.

P.S. I would suggest you use the fetch() interface for writing new code, not the XMLHttpRequest API. fetch() is just much easier to use and a more modern design (using promises).

CodePudding user response:

Try to set the header after you call the open function

xhr.open('POST', 'http://localhost:3000/frases');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(frase);
  •  Tags:  
  • Related