Javascript Node.JS:从服务器端内存提供文件与服务器端文件

Javascript Node.JS:从服务器端内存提供文件与服务器端文件,javascript,node.js,express,download,Javascript,Node.js,Express,Download,我的节点服务器从外部API获取文件内容(base64字符串)。我希望客户端将内存中的base64字符串作为文件下载。但是,该文件在客户端浏览器下载后已损坏 如果我获取相同的文件内容,使用fs将其保存到服务器的本地文件夹,然后将该文件发送到客户端,则该文件将正确保存在客户端系统上 当我看一下这两组十六进制数据之间的差异时,有区别也有相似之处 以前有没有人克服过这个问题,或者有一个理论解释为什么一个有效而另一个无效如果可能,我想尽量避免在服务器上保存文件。 attachment.Name = 'pi

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

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

当我看一下这两组十六进制数据之间的差异时,有区别也有相似之处

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

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
内存下载服务代码(文件在客户端计算机上一旦损坏):

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();
});
注意:以下变量
内容
的十六进制表示形式与有效文件的十六进制数据相同

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();
});

这解决了我的问题。发送到客户机的是一个适当字节的缓冲区,而不是一个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)”