req.body undefined on get but not on post using axios and multer

Issue

I am sending user login and registration data with axios to my backend as get and post requests respectively, but I can’t figure out why for the login (get) request, the req.body in express is undefined even though everything seems perfectly identical

In the react app I sent axios requests as shown:

const axiosConfig = {
headers: { "Content-Type": "multipart/form-data" }, // commenting this out and using defaults does nothing
};

function submitHandler(e) {
  e.preventDefault();
  const axiosUser = axios.create({ baseURL: "http://localhost:3100" });

  let userData = new FormData();
  userData.append("username", usernameRef.current.value);
  userData.append("password", passwordRef.current.value);

  if (formState === "login") {
    for (let pair of userData.entries()) {
      console.log(pair[0] + ", " + pair[1]); // username, x // password y as expected
    }

    console.log("LOGIN");
    axiosUser
      .get("/u", userData, axiosConfig)
      .then((res) => console.log("success:", res))
      .catch((err) => console.log("error:", err))
      .then(() => {
        navigate("/");
      });
  } else {
    for (let pair of userData.entries()) {
      console.log(pair[0] + ", " + pair[1]); // username, x // password y as expected
    }

    console.log("REGISTER");
    axiosUser
      .post("/u", userData, axiosConfig)
      .then((res) => console.log("success:", res))
      .catch((err) => console.log("error:", err))
      .then(() => {
        navigate("/");
      });
  }
}

In express, I parse the formData using multer upload.none() as my other routes do have image uploads to cloudinary:

const upload = multer({ storage }) // cloudinary storage

app.post(
  "/u",
  upload.none(),
  asyncErrorWrapper(async function (req, res) {
    const result = await User.findOne({ username: req.body.username });
    console.log(result);
    if (result) {
      console.log(req.body.username);
      return res.status(400).send("username already exists");
    }

    const hashedPw = bcrypt.hashSync(req.body.password, 10);

    const newUser = new User({
      username: req.body.username,
      password: hashedPw,
    });
    await newUser.save();
    console.log(newUser);
    console.log(`  > new user "${req.body.username}" created`);
    res.status(200).send("user created");
  })
);

app.get(
  "/u",
  upload.none(),
  asyncErrorWrapper(async function (req, res) {
    console.log("LOGIN");
    console.log(req.body); // ! undefined, {} if parsed with bodyParser
    console.log(req.body.username); // error, undefined with bodyParser
    console.log(req.body.password); // error, undefined with bodyParser
    res.send(req.body);
  })
);

I have tried removing axiosConfig which did not change anything, and using another parser like bodyParser in place of multer logs req.body as an empty object.

Solution

Get Requests usually do not have bodies. Only Post/Put etc Requests have some. While some implementations would theoretically support Get requests with bodies, it is not recommended to do so and not within the HTTP specification.

If you take a look at the axios documentation it does not specify the possibility to add a body to axios.get only the request config.

You should also use a Post request for your login function.

Answered By – Lalaluka

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published