0

I'm trying to upload files to my database but I'm having trouble.

When I try to upload a file to my database I got this error : Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

And the data from my file is not save to my database (see the image) : enter image description here

I think my problem is here :

  const fileData = {
    type: req.body.type,
    name: req.body.name,
    data: req.body.data
  };

I tried to copy the function I use for create a user when he register but for a file when someone upload it.

Register (it works) :

users.post("/register", (req, res) => {
  const today = new Date();
  const userData = {
    first_name: req.body.first_name,
    last_name: req.body.last_name,
    email: req.body.email,
    password: req.body.password,
    phone: req.body.phone,
    deliveryAddress: req.body.deliveryAddress,
    created: today
  };

  User.findOne({
    where: {
      email: req.body.email
    }
  })
    //TODO bcrypt
    .then(user => {
      if (!user) {
        bcrypt.hash(req.body.password, 10, (err, hash) => {
          userData.password = hash;
          User.create(userData)
            .then(user => {
              res.json({ status: user.email + " registered!" });
            })
            .catch(err => {
              res.send("error: " + err);
            });
        });
      } else {
        res.status(400).json({ error: "Email already taken" });
        console.log("Email already taken !");
      }
    })
    .catch(err => {
      res.status(400).json("Error : " + err);
    });
});

File upload (not working) :

app.post("/files", (req, res) => {
  const uploadFile = req.files.file;
  const fileName = req.files.file.name;
  const fileData = {
    type: req.body.type,
    name: req.body.name,
    data: req.body.data
  };
  uploadFile.mv(`./uploads/${fileName}`, function(err) {
    if (err) {
      return res.status(500).send(err);
    }
    res.json({
      file: `uploads/${fileName}`
    });
  });
  Upload.findOne({
    where: {
      name: req.body.name
    }
  })
    .then(file => {
      if (!file) {
        Upload.create(fileData)
          .then(file => {
            res.json({ status: file.name + " created !" });
          })
          .catch(err => {
            res.send("error: " + err);
          });
      } else {
        res.status(400).json({ error: "File already uploaded" });
        console.log("File already uploaded");
      }
    })
    .catch(err => {
      res.status(400).json("Error : " + err);
    });
});

I'm not very familiar with backend so... I tried to change :

  const fileData = {
    type: req.body.type,
    name: req.body.name,
    data: req.body.data
  };

with

  const fileData = {
    type: req.files.file.type,
    name: req.files.file.name,
    data: req.files.file.data
  };

But I got an infinite loop and the file is not uploaded to my database (nothing is created).

The upload to the backend (uploads folder) works.

EDIT

When I use req.files.file.something for the fileData it works sometimes, the file is correctly uploaded to database but I got the error again (I think it works when the file is very tiny).

For a 1 Ko file :

Executing (default): INSERT INTO `files` (`id`,`name`,`data`,`createdAt`,`updatedAt`) VALUES (DEFAULT,'a suprimer.html',X'3c21444f43545950452068746d6c3e0d0a0d0a3c21444f43545950452068746d6c3e0d0a3c68746d6c3e0d0a3c686561643e200d0a093c6d65746120636861727365743d227574662d38223e0d0a093c7469746c653e20466169726520756e6520696d6167653c2f7469746c653e0d0a3c2f686561643e0d0a3c626f64793e0d0a0d0a093c703e746573743c2f703e0d0a0d0a093c696d67207372633d2268642e696d6167652e736e6f772e6a706567223e0d0a090d0a0d0a3c2f626f64793e0d0a3c2f68746d6c3e','2020-01-29 10:07:28','2020-01-29 10:07:28');

And in the database : enter image description here

Why the type is not set up ? How can I reduce the time of the upload for a bigger file ?

leyh
  • 241
  • 2
  • 4
  • 13

2 Answers2

0

I believe this is because you are trying to send two responses in the same call handler. Once in uploadfile.mv then again in Upload.findOne. You cannot return two res.X to the same request.

This thread might be useful: Error: Can't set headers after they are sent to the client

lawrence-witt
  • 8,094
  • 3
  • 13
  • 32
0

You can try this code below:

app.post("/files", (req, res) => {
  const uploadFile = req.files.file;
  const fileName = req.files.file.name;
  const fileData = {
    type: req.body.type,
    name: req.body.name,
    data: req.body.data
  };
  Upload.findOne({
    where: {
      name: req.body.name
    }
  }).then(file => {
      if (!file) {
        // upload file to directory
        uploadFile.mv(`./uploads/${fileName}`);
        // save file to database
        Upload.create(fileData)
          .then(file => {
            return res.json({ status: file.name + " created !" });
          }).catch(err => {
            return res.send("error: " + err);
          });
      } else {
        return res.status(400).json({ error: "File already uploaded" });
      }
    })
    .catch(err => {
      return res.status(400).json("Error : " + err);
    });
});

I hope it can help you to upload your file.

Titus Sutio Fanpula
  • 3,467
  • 4
  • 14
  • 33