Request body is empty when posting form-data
Asked Answered
I

6

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.

Invocate answered 7/6, 2019 at 11:45 Comment(4)
for parsing application/x-www-form-urlencoded, aren't you supposed to use app.use(bodyParser.urlencoded({ extended: false })) ?Bazluke
Tried this as well. Not workingInvocate
https://mcmap.net/q/80620/-req-body-empty-on-posts this may help youBazluke
Already looked at this...Nothing helpedInvocate
W
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);
       });
   });
})
Wozniak answered 7/6, 2019 at 16:43 Comment(3)
Can you please elaborate more why req.body is empty?Invocate
@Invocate 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.Wozniak
@Wozniak Why can't Express handle such a common use case? Is a library 100% necessary?Lind
A
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: "[email protected]", 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: '[email protected]', password: '123' } }
Alburga answered 17/5, 2020 at 11:21 Comment(0)
A
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.

Aminopyrine answered 12/6, 2019 at 10:44 Comment(0)
T
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()); 
Toady answered 23/8, 2020 at 11:5 Comment(0)
M
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 .

Moderation answered 6/5, 2022 at 8:46 Comment(0)
S
-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.

Sankaran answered 1/7, 2021 at 12:58 Comment(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.Matthieu

© 2022 - 2024 — McMap. All rights reserved.