Sam
Sam

Reputation: 2331

Javascript fetch(POST) to express server fails. The server does not receive the request from JS, but receives request from Postman

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);
    })
});

Upvotes: 0

Views: 2290

Answers (2)

Sam
Sam

Reputation: 2331

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))

Upvotes: 0

Sujit Kumar Singh
Sujit Kumar Singh

Reputation: 1088

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
});

Upvotes: 2

Related Questions