Search code examples
javascriptnode.jsreactjspostfetch

The req.body is empty in node.js sent from react


I create an app in react. I am trying to use fetch with a post to a different port of localhost. I received the req on the server, but my body is empty. Why my body is empty? I don't understand.

Code in React function:

export default function Sending() {
    async function handleSubmit(e) {
          e.preventDefault()
          try{
              let result = await fetch('http://localhost:5000',{
                method: 'post',
                mode: 'no-cors',
                headers: {
                  'Accept': 'application/json',
                  'Content-type': 'application/json',
                },
                body: JSON.stringify({ email: '[email protected]' })
              })
    
              console.log(result)
          } catch (error){
            console.log(error)
          }
    }
 return (
    <>
      Have a Form here
    </>
  )
}

the console log of browser:

Response {type: "opaque", url: "", redirected: false, status: 0, ok: false, …}
  body: null 
  bodyUsed: false 
  headers: 
  Headers {} 
  ok: false
  redirected: false 
  status: 0 
  statusText: "" 
  type: "opaque" 
  url: ""
  __proto__: Response

my simple server hold on node.js:

const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const port = process.env.PORT || 5000

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.post('/', (req, res) => {
  console.log(req.body)
  res.send("Hello")
})

app.get('/hello', (req, res) => {
  res.send("Hello, Benny")
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

Solution

    1. You are trying to post JSON
    2. To do that you need to set a 'Content-type': 'application/json' request header
    3. This is only allowed on a cross-origin request when you have permission from CORS (from a preflight request).
    4. You said mode: 'no-cors', a declaration that you do not have or want permission to do anything from CORS, so the browser will silently ignore anything that needs CORS permission
    5. The request arrives at the server without 'Content-type': 'application/json' so the body-parser doesn't know that it needs to decode the JSON

    You need to:

    • Remove mode: 'no-cors'
    • Configure the server to support CORS including for preflight requests

    This is most easily done with the cors module

    const cors = require('cors')
    const app = express()
    
    const corsOptions = {
      origin: 'http://example.com',
    }
    
    const configuredCors = cors(corsOptions);
    
    app.options('*', configuredCors)
    
    app.post('/', configuredCors, (req, res) => {
      console.log(req.body)
      res.send("Hello")
    })