更新:
感谢@ jfriend00的建议,这是更好,更有效地直接发送缓冲区,以客户为文件,而不是在服务器磁盘先保存它。
实现,stream.PassThrough()
,可用于pipe()
,这里有一个例子:
var stream = require('stream');
//...
app.get('/download', function(request, response){
//...
var fileContents = Buffer.from(fileData, "base64");
var readStream = new stream.PassThrough();
readStream.end(fileContents);
response.set('Content-disposition', 'attachment; filename=' + fileName);
response.set('Content-Type', 'text/plain');
readStream.pipe(res);
});
根据快递document,res.download()
API是:
res.download(路径[,文件名] [,fn])
将路径中的文件作为“附件”传输。通常,浏览器会提示用户下载。默认情况下,Content-Disposition头文件“filename =”参数是路径(通常出现在浏览器对话框中)。用filename参数覆盖这个默认值。
请注意res.download()
的第一个参数是一个“路径”,它表示将要下载的服务器中的文件路径。在你的代码中,第一个参数是一个Buffer,这就是为什么Node.js会抱怨“filename参数必须是一个字符串” - 默认情况下,Content-Disposition
头文件“filename =”参数是路径。
要使用res.download()
你的代码工作,你需要在fileData
服务器保存为一个文件,然后调用res.download()
与该文件的路径:
var fs = require('fs');
//...
app.get('/download', function(request, response){
//...
var fileContents = Buffer.from(fileData, "base64");
var savedFilePath = '/temp/' + fileName; // in some convenient temporary file folder
fs.writeFile(savedFilePath, fileContents, function() {
response.status(200).download(savedFilePath, fileName);
});
});
另外,请注意new Buffer(string[, encoding])
现在已经过时了。最好使用Buffer.from(string[, encoding])
。
哪一行给出错误? –
请用'let'声明你的局部变量,如'fileType','fileName'和'fileData'。在服务器中使用偶然的全局变量是一种灾难。 – jfriend00
如果你看[res.download()']代码(https://github.com/expressjs/express/blob/master/lib/response.js#L514),你可以看到它只是调用'res.sendFile()'所以它只能用来从文件中发送数据,而不是从内存中发送数据。您将不得不寻找一种不同的方式直接从内存发送或首先写入临时文件。 – jfriend00