How to send files with NodeJS? (Getting errors when I open sent files)

Viewed 30

I have already written this question many times and I cannot find an answer from anyone, so I am going to try to make it as detailed as possible to see if anyone knows what is happening since I have been blocked for more than a week due to this error.

I am making a website with React and its respective API with NodeJS. There is a part of the web where a trainee uploads the trainee's training and then the trainee can download it. The part of uploading the file is already implemented and it works 100%, the problem comes when I have to download these files. When I download and open them I receive the following message (translation of the error: an error occurred when loading the PDF document): Error I get when I open the pdf in Spanish

I really don't know what I'm doing wrong, that's why below I leave you the express controller code that I use in the nodejs code for this api functionality:

routerTrainer.get("/download-training", verifyJWT, async (req, res) => {
  const { training_id } = req.headers;

  let training = await Training.findOne({
    where: { id: training_id },
  });

  if (training) {
    res.download(`${path}${dirname}${training.file_id}`);
  }
});

Several comments to make about it. First of all I am using res.download() although I have also used many others such as res.sendFile() or I have also used the fs library to make a file.pipe(res) and none of them have worked for me. Also add that I am 100% sure that the file path is fine, I have already checked it as well and finally add that the verifyJWT middleware has nothing to do with it, it is simply a verifier of the Json Web Tokens token.

Now we are going to move on to the React part, here in the code I have also tried a lot of things, I have even used libraries like file-saver and it has not worked for me either (I don't know if the error is in the frontend or in the backend) . Here is the React download function code:

const downloadTraining = async (id) => {
    const fileReader = new FileReader();
    const JWT = new ClassJWT();
    const axiosReq = axios.create();
    await JWT.checkJWT();
    axiosReq
      .get(`${serverPath}/download-training`, {
        headers: {
          training_id: id,
          token: JWT.getToken(),
          responseType: "blob",
        },
      })
      .then((res) => {
        console.log(res);
        fileReader.readAsDataURL(new Blob([res.data]));
      })
      .catch((err) => console.log(err));

    fileReader.addEventListener("loadend", () => {
      const blobString = fileReader.result;
      const link = document.createElement("a");
      link.href = blobString;
      link.setAttribute("download", "file.pdf");
      document.body.appendChild(link);
      link.click();
    });
  };

I think everything is here, please ask if anything is missing, I tell you I'm starting to be a little desperate because I've already lost more than a week for this error and I can't find the answer anywhere.

Please, if anyone knows what may be happening, do not hesitate to answer.

1 Answers

If you look at the documentation, I think the responseType is not a header but a separate option (See https://github.com/axios/axios#request-config).

You can give a try with the responseType as arraybuffer ?

 ...
 axiosReq
  .get(`${serverPath}/download-training`, {
    headers: {
      training_id: id,
      token: JWT.getToken(),
    },
    responseType: "arraybuffer",
  })
  ...
Related