【问题标题】:Downloading file with node express app as response使用 node express 应用程序下载文件作为响应
【发布时间】:2019-11-26 16:39:01
【问题描述】:

我在使用 express 应用时遇到问题。我正在使用 multer 上传文件,然后使用 res.download 将文件发回。这似乎适用于文本文件,但图像不起作用。当我将文件发送到客户端时,文件大小实际上比服务器上的要小一点。似乎没有传输完整的文件。

我没有对我只是使用 res.download 的响应做任何花哨的事情。我基本上研究了我能找到的每一篇文章,似乎这对其他人都有效。

只有文本文件有效。 Word、excel、pdf 都说下载时损坏了。

编辑:这是运行 res.download 的函数。它传递了文件路径、mimetype 等。

function downloadFile(req, res) {   
    let fpath = req.body.path; 
    let originalName = req.body.originalName;
    let mimetype = req.body.mimetype;
    let filename = req.body.filename;

    res.download(fpath, originalName, function(err) {
        if (err) {
            console.log(err);
        }        
    });

}

编辑:这是我的 redux thunk,它发出请求并触发文件下载。下载函数来自downloadjs库。

export const downloadFile = (path, originalName, mimetype, filename) => { 
    return dispatch => {                
        return axios.post('/api/v1/quotes/downloadFile', { path: path, originalName: originalName, mimetype: mimetype, filename: filename })
        .then(res => {                
            if (res.status !== 200) {
                ErrorHandler.logError(res);                
            } 
            else {                                        
               // download(res.data, originalName);             
               download(new Blob([res.data]), originalName, mimetype);
            }         
        }).catch(function(error) {
            ErrorHandler.logError(error);                               
        });
    }
}

编辑:这是我在网络标签中看到的一小部分示例。看起来像它的图像内容,但大小比服务器上的要小,当我尝试打开它时,我得到一个不受支持的文件类型错误。

PNG


IHDR{>õIÖÕsRGB®ÎégAMA±üa    pHYsÃÃÇo¨d+{IDATx^íÝml\×ßq¾jº]´Mv´¤ÛÅvÛnÛEßt4/vQ[äÅ¢¯òb>-
él²æJv$Ǧ(ѦDÉR$R
¥V-Q6mÅ4kF¶®,U%ÊYS¶åDr¼5ÿ=ÿ{Ï9sîÌ!Gßp@Î}¾çÞ9÷7÷Þ¹Ó!¸o/ÛÚaï>MOJ4µ¸aíÐF{÷ég?ùó?µÚa a=öFØHa a=öFØHa 

请求标头

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 160
Content-Type: application/json;charset=UTF-8
Host: localhost:3000
Origin: http://localhost:3000
Referer: http://localhost:3000/Quote
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36

响应标头

accept-ranges: bytes
cache-control: public, max-age=0
connection: close
content-disposition: attachment; filename="sSubLineConfigIds.PNG"
content-length: 11238
content-type: application/octet-stream
date: Wed, 17 Jul 2019 19:03:54 GMT
etag: W/"2be6-16c0151b84a"
last-modified: Wed, 17 Jul 2019 19:03:48 GMT
x-powered-by: Express

【问题讨论】:

  • 请添加您所指的`res.download`代码。这样我们就可以了解正在发生的事情。
  • 我添加了它的名称,没有太多内容。我可以抓住任何其他有用的东西。

标签: javascript node.js reactjs express


【解决方案1】:

我能够弄清楚这一点。我最终做的是将文件转换为 base64 并将下载链接设置为该 base64 字符串。

构建base64字符串的节点函数。

function downloadFile(req, res) {   
    let fpath = req.body.path;   
    let mimetype = req.body.mimetype; 

    fs.readFile(fpath, function (err, data) {        
        if (err) res.status(500).send('File could not be downloaded');

        var base64 = Buffer.from(data).toString('base64');
        base64='data:' + mimetype + ';base64,'+base64;
        res.send(base64);
    });  
}

这里是构建链接、模拟点击并将源链接设置为 base64 字符串的客户端代码。

export const downloadFile = (path, originalName, mimetype, filename) => { 
    return dispatch => {                
        return axios.post('/api/v1/quotes/downloadFile', { path: path, originalName: originalName, mimetype: mimetype, filename: filename })
        .then(res => {                
            if (res.status !== 200) {
                ErrorHandler.logError(res);                
            } 
            else {                        
                const linkSource = res.data;
                const downloadLink = document.createElement("a");
                const fileName = originalName;

                downloadLink.href = linkSource;
                downloadLink.download = fileName;
                downloadLink.click();                        
            }         
        }).catch(function(error) {
            ErrorHandler.logError(error);                               
        });
    }
}

【讨论】:

    【解决方案2】:

    根据共享的代码,一切看起来都很好。 看起来这个请求是通过 XHR 从您的前端发起的,而不是您必须编写下载逻辑来将响应转换为 blob,然后创建一个文件以供下载,如提到的 how-to-create-a-dynamic-file-link-for-download-in-javascript

    【讨论】:

    • 我会试一试。我将使用此信息编辑帖子,但在我的 redux 操作中,我实际上使用的是 downloadjs 来下载文件。我会把代码放在上面。
    • 似乎该代码更关注如何下载文件,这不是我的问题。我可以使用 downloadjs 库触发下载,但之后无法打开文件而不会出现错误。
    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    相关资源
    最近更新 更多