我在使用 ReactJS 从 Nodejs 下载文件时遇到问题

I've got an issue with ReactJS to download a file from Nodejs

我在一个问题上需要一些帮助。我尝试从我的服务器 Nodejs 下载我的客户端 ReactJs 上的文件。 我进入了我的 server.js :

router.route("/download/:filesaveas").get(function(req, res) {
  const fileLocation = "public/files/" + req.params.filesaveas;
  const file = req.params.filesaveas;
  res.download(fileLocation, file, (err) => {
    if (err) console.log(err);
});

当我尝试直接从服务器 http://localhost:4000/cww/download/testfile.pdf 下载时,下载成功,我没有任何错误,文件也没有损坏。

在我的客户端,我有一个函数 downloadFile,它由按钮“onclick”操作调用。

import download from 'downloadjs'

downloadFile = (filetodownload) => {
        axios.get('http://localhost:4000/cww/download/'+filetodownload)
        .then(res => {
            var filename = "testfile.pdf"
            download(res.data, scriptname, "text/plain");
        });
     }

当我点击按钮时。下载了一些东西,但文件似乎已损坏。无法打开...我想,服务器的响应数据有问题。 通过执行 console.log(res.data),我可以看到我的内容 PDF 的一部分,但有些奇怪 字符(如编码)但无法下载正确的文件。

感谢您的帮助。

如果您想要最简单的选择是打开一个包含该文件地址的新选项卡,该选项卡仅在路由为 public.

时有效
const newTab = false;
window.open('http://localhost:4000/cww/download/testfile.pdf',newTab ? '' : '_self' );

但是你可以在不触及文件编码的情况下完成它,甚至可以为此使用 axios:

  onClick() {
    const fileName = 'testfile.pdf';
    fetch('http://localhost:4000/cww/download/testfile.pdf', {
      method: 'GET',
      headers: {
       'Content-Type': 'application/json'
       // Security Headers if needed
      },
      body: undefined,
    })
      .then((data) => {
        return data.blob();
      })
      .then((data) => {
        if (data.size === 0) {
          throw new Error('File not found');
        }
        const fileURL = URL.createObjectURL(data);
        const downloadLink = document.createElement('a');
        downloadLink.href = fileURL;
        downloadLink.download = fileName;
        downloadLink.click();
      })
      .catch((err) => {
        console.log(err);
        //  Error Action
      });
  }

后端将简单地将文件流式传输给用户。

我不太了解 res.download(可能是更好的解决方案)

import * as fs from 'fs';

export async function getFile(request, response) {

  const fileStream = fs.createReadStream('yourFileAddress', {});


  fileStream.on('error', (err) => {
    console.log(err.message);
    response.status(404).send();
    fileStream.removeAllListeners();
  });

  fileStream.on('end', () => {
    console.log('Streamed successfully to user');
    fileStream.removeAllListeners();
  });

  // finally starting the stream
  fileStream.pipe(response);

}

感谢您的帮助!我刚刚发现我的错误! 我忘了添加 ReponseType: blob,现在它完美运行了 ;-)

downloadFile = (filetodownload) => {
        axios.get('http://localhost:4000/cww/download/'+filetodownload, {responseType: 'blob'})
        .then(res => {
            var filename = "testfile.pdf"
            download(res.data, scriptname, "text/plain");
        });
     }