0

MRE -> node-server : react app


When I send a POST request using Postman, I get the expected result. This is the request that I am sending using Postman

enter image description here

and test sent gets printed to the console of my node server

If I send a request from my react form however, test sent does not print to the console, but the catch block of my fetch request get's executed and err is printed to the console of my react app, followed by {}.

I would like to know why my POST request is not working and is not getting received by the server


Below is the function that I call when someone clicks the submission button of my form created in react

Function called on form submission

nodeUrl = 'https://localhost:6060?'

const submitData = async () => {

    fetch(nodeUrl, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({'test': 'test'})
    }).then((res) => {
      alert('then')
    }).catch((err) => {
      alert('err')
      alert(JSON.stringify(err))
    })
  }
}

This is the server that I run using node server.js

server.js

server.post('/', function(req, res) {
    console.log('test sent')    
    mailer.messages().send(req.body)
    .then((mes) => {
        console.log(mes)
        res.json({ message: 'Thanks for your message. Our service team has been notified and will get back to you shortly.' })
    }).catch(err => {
        console.log(err)
        res.json(err);
    })
});
7
  • You define nodeUrl, but are trying to access it via a property on the data object. Could this be your problem? Commented Sep 30, 2020 at 16:48
  • @camwhite Sorry, I changed it in here, that's not the problem, I was just trying to make this post easier to read. Everything else is basically identical Commented Sep 30, 2020 at 16:53
  • What error do you see in the console of your browser? Does is say something related to "Cross Origin" or CORS request? You can also try updating the nodeUrl variable to replace that last ? with "/". Commented Sep 30, 2020 at 17:06
  • It says err because of the alert('err') and then when I alert the err object I see {} Commented Sep 30, 2020 at 17:23
  • You will see complete detail in the Network tab of the developer tool. Select the XHR tab under the filter section. Commented Sep 30, 2020 at 17:27

2 Answers 2

2

The majour issue here is due to CORS. CORS support can be used to overcome this. Just keep in mind to have this only for development mode(see below codes).

But, as per the Postman's snapshot and provided GitHub repositories, the request from Front-end should be of multipart/form-data type. Thus, the Front-end code would look like this

const nodeUrl = "http://localhost:6060/";

const submitData = async () => {
  // create a FormData object
  const formData = new FormData();
  formData.append('form', '[email protected]');
  formData.append('to', '[email protected]');

  // this auto adds 'multipart/form-data' + HASH header in the request
  fetch(nodeUrl, {
    method: "POST",
    body: formData
  })
    .then(res => {
      console.log(res);
    }).catch(err => {
      console.log('Error -', err);
    });
};

To handle multipart/form-data request in the ExpressJS, you need a plugin Multer.

const express = require('express');
const bodyParser = require('body-parser');
const multer  = require('multer'); // for 'multipart' type request
const server = express();
const upload = multer();

// allow CORS requests in development mode
if (process.env.NODE_ENV === 'development') {
  // Server run command - "NODE_ENV=development node server.js"
  const cors = require('cors');
  server.use(cors());
}

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

// using Multer middleware form extracting 'FormData' payload
server.post('/', upload.none(), function(req, res) {
  console.log('Received body', req.body);
  ... // other codes
});

Strategy 2(plain JSON) -

If that 'multipart/form-data' strategy was unintentional and you just want to send simple JSON, use below codes -

In Front-end, trigger API request as -

fetch(nodeUrl, {
  method: "POST",
  headers: {
    'Content-Type': 'application/json', // this needs to be defined
  },
  body: JSON.stringify({ from: '[email protected]', to: '[email protected]' })
})

In server, just ignore codes related to Multer and only keep your API as -

server.post('/', function(req, res) {
  console.log('Received body', req.body);
  ... // other codes
});
Sign up to request clarification or add additional context in comments.

9 Comments

What is a method that would work in production mode?
Do you know a resource where I could learn a little more about this, that's really dumbed down or split in jot notes or diagrams?
In production, the static files(HTML, JS and CSS) will be under the root domain. There the requests would by default come from the same origin. There wouldn't be any issue related to the CORS request.
@Sam found Mozilla's doc with graphical representation and a technical explanation and solution blog. However, I am still waiting for your confirmation that it is really a CORS issue. If it is not then my answer would be irrelevant to your problem.
This solution, in addition to the fetch request that I posted in my answer lead to a working solution
|
0

I ended up using a better fetch request, which was put together for me by selecting code -> Javascript Fetch in Postman(under the save button)

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

var urlencoded = new URLSearchParams();
urlencoded.append("from", "[email protected]");
urlencoded.append("test", "test");

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: urlencoded,
  redirect: 'follow'
};

fetch("http:localhost:6060/, requestOptions)
  .then(response => {
    if (response.ok){
      response.json().then(json => {
        console.log(json)
      })
    }
  })
  .catch(error => console.log('error: ', error))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.