【问题标题】:Node.JS: Serving a File from Server-Side Memory vs Server-Side FileNode.JS:从服务器端内存提供文件与服务器端文件
【发布时间】:2016-05-02 20:45:57
【问题描述】:

我的节点服务器从外部 API 获取文件内容(base64 字符串)。我希望客户端将内存中的 base64 字符串作为文件下载。但是,在客户端的浏览器下载后文件已损坏。

如果我获取相同的文件内容,使用 fs 将它们保存到服务器的本地文件夹,然后将该文件发送到客户端,该文件将正确保存在客户端的系统上。

当我看一下两组十六进制数据之间的差异时,有区别也有相似之处。 comparison screenshot, valid file is on top

以前有没有人解决过这个问题,或者有一个关于为什么一个有效而另一个无效的理论? 如果可能,我想尽量避免将文件保存在我的服务器上的步骤。

attachment.Name = 'picture.jpg'; //this can be any type of file
attachment.ContentType = 'image/jpeg'; //just an example with an image
attachment.ContentBytes = 'iVBORw0KGgoAAAAN.....' //long but complete base64 string

提供内存下载的代码(文件在客户端机器上损坏一次):

注意:以下变量 contents 的十六进制表示与有效文件的十六进制数据相同

var atob = require('atob');

//tell the browser to download this
res.setHeader('Content-disposition', 'attachment; filename=' + attachment.Name);
res.setHeader('Content-type', attachment.ContentType);

var contents = atob(attachment.ContentBytes);

return res.send(200, contents);

还有

提供本地文件下载的代码(文件在客户端机器上一次有效):

var fs = require("fs");
var directory = "temporary/" + attachment.Name;

//tell the browser to download this
res.setHeader('Content-disposition', 'attachment; filename=' + attachment.Name);
res.setHeader('Content-type', attachment.ContentType);

//save the file on the server temporarily
fs.writeFile(directory, attachment.ContentBytes, 'base64', function(err)
{
    if (err)
    {
        console.log(err);
        return res.serverError();
    }                   
});

//send the file to the client
var fileStream = fs.createReadStream(directory);
fileStream.pipe(res);

//once the file is sent, send 200 and delete the file from the server
fileStream.on('end', function ()
{
    fs.unlink(directory);
    return res.ok();
});

【问题讨论】:

    标签: javascript node.js express download


    【解决方案1】:

    这解决了我的问题。发送到客户端的是适当字节的缓冲区,而不是 ASCII 字符串。浏览器似乎很乐​​意接受这一点。

    //tell the browser to download this
    res.setHeader('Content-disposition', 'attachment; filename=' + attachment.Name);
    res.setHeader('Content-type', attachment.ContentType);
    
    //convert to a buffer and send to client
    var fileContents = new Buffer(attachment.ContentBytes, "base64");
    
    return res.send(200, fileContents);
    

    【讨论】:

    • 已弃用。我收到此错误消息'express deprecated res.send(status, body): Use res.status(status).send(body)'
    猜你喜欢
    • 1970-01-01
    • 2012-01-17
    • 2020-04-23
    • 1970-01-01
    • 2015-07-25
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    相关资源
    最近更新 更多