6

I'm using a simple post request to my backend for a form data and for some reason the body is alwayes empty. I'm trying to isolate this so i changed the content type to application json and changed the data to json and only this way i can send data.

Client side:

submitForm(event) {
        event.preventDefault();
        console.log("gggg");
        const data = new FormData(event.target);

         axios.post("http://localhost:4000/user-form-post",data).then(function (response) {
            //handle success
            console.log(response);
        })
        .catch(function (response) {
            //handle error
            console.log(response);
        });

Server side:

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

app.use(express.urlencoded());

// Parse JSON bodies (as sent by API clients)
app.use(express.json());

app.use(logger('dev'));
app.post('/user-form-post', (req,res) =>{

    console.log("dfdf");
    console.log(req.body); // alwayes print empty dict {}
    res.end();

})

This is not working because it expects jsons(expected behavior):

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

Same behavior with Postman.

KaramJaber
  • 851
  • 5
  • 13
  • 24

6 Answers6

5

You will need to parse your form data from express side. For this you will have to use multer or multiparty. Try something like this. refer the documentation as well

const multiparty = require('multiparty');

app.post('/user-form-post', (req,res) =>{

   let form = new multiparty.Form();

   form.parse(req, function(err, fields, files) {
      Object.keys(fields).forEach(function(name) {
           console.log('got field named ' + name);
       });
   });
})
TRomesh
  • 4,323
  • 8
  • 44
  • 74
  • 1
    Can you please elaborate more why req.body is empty? – KaramJaber Jun 08 '19 at 21:55
  • @KaramJaber This is because you are sending form data from the front-end and express can not parse form data. For that you will have to use some kind of a middlewares which is capable of parsing form data. The most famous middleware are multer and multiparty. – TRomesh Jun 09 '19 at 04:11
  • 2
    @TRomesh Why can't Express handle such a common use case? Is a library 100% necessary? – Ivan Jan 11 '21 at 05:41
2

when it comes to my issue, i have this front end

 const form = new FormData();
      form.email = this.email;
      form.password = this.password;
      console.log("onSubmit -> form", form);

axios.post("http://localhost:3000/register",  form )

onSubmit -> form FormData {email: "admin@gmail.com", password: "123"}

but the req.body in backend is empty, and i figured it out that the form in axios.post still need 1 more bracket {} even it's a object. like this

axios.post("http://localhost:3000/register", { form })

After that backend got body like this

req.body = { form: { email: 'admin@gmail.com', password: '123' } }
ali emili
  • 538
  • 2
  • 6
  • 19
Mark Sparrow
  • 191
  • 3
  • 9
0

A problem with request body when you post data is data type .

I have recently a problem with Postman . You should post data with type x-www-form-urlencoded or raw->JSON to fix the problem.

Goodluck.

Le Quang
  • 515
  • 4
  • 10
0

You are using:

app.use( bodyParser.json() );  // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
  extended: true
}));

Please, also use given below line code but first install multer and write the code in top of your application:

var multer = require('multer');
var upload = multer();

app.use(express.json()); 
Guilherme Lemmi
  • 3,271
  • 7
  • 30
  • 30
0

Faced the same issue , spent 2 days . Here are the solutions i found :

  1. my request payload had JSON.stringify() , it will make body as {} empty object . when i removed JSON.stringify() and sent request it worked .
  2. Content type should be multipart-form :boundary -----
  3. Now if i externally set it to multipart-form , boundary thing was missing. for few people it worked when you set content-type as false / undefined , boundary thing got added up,but not for me .
  4. Even though i followed all steps and sending FormData as payload, payload was request payload object in network tab and was not FormData object , my request failed with 500 .
  5. i tried the below code , its react + typescript (make necessary changes to avoid syntax errors)

import QueryString from 'qs';
import { ApiParams } from './xyzfile';
import { ApiHandlerRawType } from './types/xyzfile';



const setDefaultOptions = ({
  method = '',
  url = '',
  params = {},
  data = {},
  signal = null,
  headers = new Headers(),
  ...options
} = {}) => ({
  method,
  url,
  params,
  signal,
  headers,
  data,
  ...options
});

const setData = ({ method, data, ...options }: ApiHandlerRawType) => {
  const option = options;
  if (method !== 'GET' && option.isStreamData) {
    option.body = data;
  }
  return {
    method,
    ...option
  };
};

const addRequestHeaders = ({ headers = new Headers(), ...options }) => {
  const { existingHeaders }: ApiHandlerRawType = options;
  if (existingHeaders) {
    Object.entries(existingHeaders).forEach(([key, value]) => {
      if (key !== 'Content-Type') headers.set(key, value);
    });
  }
  return {
    headers,
    ...options
  };
};

export const ApiHandlerRaw = ({
  url,
  ...originalOptions
}: ApiHandlerRawType): Promise<Response> => {
  const options = setData(
    addRequestHeaders(setDefaultOptions(originalOptions))
  );
  return fetch(url || '', options)
    .then(response => {
      if (!response.ok) throw new Error(response.statusText);
      return Promise.resolve(response);
    })
    .catch(err => Promise.reject(err));
};

export const FileUploadApiHandler = async ({
  headers,
  ...options
}: ApiHandlerRawType): Promise<Response | Blob> => {
  const response = await ApiHandlerRaw({
    headers,
    isStreamData: true,
    ...options
  });
  return response;
};

    export const fileApiService = ({
      url,
      method,
      qsObject,
      headers,
      reqObjectAsStreamData
    }: ApiParams): Promise<Response> => {
      const qs = QueryString.stringify(qsObject, { addQueryPrefix: true });
      const urlPath = `${url}${qs}`;
      const data = reqObjectAsStreamData;
      const existingHeaders = headers;
      return FileUploadApiHandler({
        url: urlPath,
        method,
        data,
        existingHeaders
      }) as Promise<Response>;
    };

send the required variables from fileApiService . existingHeaders would be your app headers , eg : token / ids ... etc . data in fileApiService is the body .

harika
  • 21
  • 3
-1

I have also faced the same issue in the published code.

But I have fixed this issue by using the below code highlighted in the attached image :-

enter image description here

There is no use of "Content-Type" to fix this issue.

Hope you fix your issue by using the above code snippets.

  • 1
    It recommended that users provide code snippets in the answer itself and not links to external sources. The code in the image can be added to the answer within a code snippet. – Omkar Khair Jul 01 '21 at 13:56