Search code examples
node.jsexpressfetchform-data

express cors request.body formData show undefined


I'm imitating cors request to express. The status is ok, and request and response are succesfull. Network shows payload filled with form data. Hovewer in nodejs terminal logs in console undefined.

Sending the form fieds with follow code:

<form id="formElt">
    <input type="text" name="FirstInput" id="" value="FirstInputValue"/>
    <input type="text" name="SecondInput" id="" value="SecondInputValue"/>
</form>
<button class="postBtn">POST</button>
<script>
postBtn.onclick = async () => {          
    let formElt = this.querySelector('#formElt');
    let fd = new FormData(formElt);
    fd.append('testInput', 'TestInputValue');
    await fetch('http://localhost:8080/add', {
        method: 'post',
        body: fd                
    })
    .then(res => {
         return res.text();                  
    })
    .then(data=>{
         p.innerText = data;
    })
}
</script>

On the nodejs side there is:

const Router = require('express');
const cors = require('cors');
const router = Router();
router.use(cors())
const postOptions = {
    origin: 'http://127.0.0.1:5500',
}
router.post('/add', cors(postOptions), (req, res)=> {
    console.log(req.body);
    res.send('hello from node! Data received!');
})

enter image description here


Solution

  • You missing code for form-data decoding in express.

    // for form-data
    const multer = require('multer');
    const forms = multer();
    router.use(forms.array());
    

    Full code HTML

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device=width, intial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="is=edge" />
        <title>Form data</title>
      </head>
    
      <body>
        <form id="formElt">
          <input type="text" name="FirstInput" id="" value="FirstInputValue" />
          <input type="text" name="SecondInput" id="" value="SecondInputValue" />
        </form>
        <button id="postBtn">POST</button>
        <script>
          postBtn.onclick = async () => {
            let formElt = document.getElementById("formElt");
            let fd = new FormData(formElt);
            fd.append("testInput", "TestInputValue");
            await fetch("http://localhost:8080/add", {
              method: "post",
              body: fd,
            })
              .then((res) => {
                return res.text();
              })
              .then((data) => {
                p.innerText = data;
              });
          }
        </script>
      </body>
    </html>
    

    server.js

    const Router = require('express');
    const cors = require('cors');
    const router = Router();
    router.use(cors())
    
    // for form-data
    const multer = require('multer');
    const forms = multer();
    router.use(forms.array()); 
    
    // for x-www-form-urlencoded
    router.use(Router.urlencoded({ extended: true }))
    
    // for raw JSON
    router.use(Router.json()); 
    
    const postOptions = {
        origin: 'http://127.0.0.1:5500',
    }
    
    router.post('/add', cors(postOptions), (req, res)=> {
        console.log(JSON.stringify(req.body, null, 4));
        res.send('hello from node! Data received!');
    })
    
    router.listen(8080, () => { console.log("Listening on :8080") })
    

    launching server

    node server.js
    

    Launch index.html from VS code by Go-Live extension. enter image description here

    received data at server.js

    enter image description here

    If using just JSON.stringify(req.body), will shows this output

        console.log(JSON.stringify(req.body));
    

    enter image description here

    POST three different Body data types. It matched server.js decoding and result at server and Postman POST call.

    enter image description here