Node Express.js-从内存下载文件-'文件名必须是字符串' [英] Node Express.js - Download file from memory - 'filename must be a string'
问题描述
我正在尝试将内存中的数据打包到一个文本文件中并将其发送给用户,从而触发文件下载。
I'm trying to package data in memory into a text file and send it to the user, triggering a file download.
我有以下代码:
app.get('/download', function(request, response){
fileType = request.query.fileType;
fileName = ( request.query.fileName + '.' + fileType ).toString();
fileData = request.query.fileData;
response.set('Content-disposition', 'attachment; filename=' + fileName );
response.set('Content-type', 'text/plain');
var fileContents = new Buffer(fileData, "base64");
response.status(200).download( fileContents );
});
它总是抛出错误,指出Content-disposition的filename参数必须是字符串。 fileName肯定是字符串,所以我不确定发生了什么。
It keeps throwing an error saying that Content-disposition's filename parameter must be a string. fileName is most certainly a string, so I'm not sure what is going on.
推荐答案
更新:
由于@ jfriend00的建议,直接将Buffer作为文件发送到客户端而不是先将其保存在服务器磁盘中会更好,更有效。
Thanks to @jfriend00's advice, it is better and more efficient to directly send Buffer to client as file, instead of saving it first in server disk.
要实现,可以使用 stream.PassThrough()
和 pipe()
,下面是一个示例:
To implement, stream.PassThrough()
and pipe()
can be used, here is an example:
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(response);
});
根据Express 文档, res.download()
API为:
res.download(路径[,文件名] [,fn])
将路径中的文件传输为一个附件。通常,浏览器会提示用户下载。默认情况下,Content-Disposition标头的 filename =参数是路径(通常显示在浏览器对话框中)。
Transfers the file at path as an "attachment". Typically, browsers will prompt the user for download. By default, the Content-Disposition header "filename=" parameter is path (this typically appears in the browser dialog). Override this default with the filename parameter.
请注意 res.download()
是路径,其指示服务器中将被下载的文件的路径。在您的代码中,第一个参数是Buffer,这就是为什么Node.js抱怨文件名参数必须是字符串的原因。 -默认情况下, Content-Disposition
标头 filename =参数为 path 。
Please note the first parameter of res.download()
is a "path", which indicates the path of file in server that would be downloaded. In your code, the first parameter is a Buffer, that's why Node.js complain that "filename parameter must be a string" -- By default, the Content-Disposition
header "filename=" parameter is path.
To使用 res.download()
使代码工作,您需要将 fileData
保存为文件在服务器中,并且然后使用该文件的路径调用 res.download()
:
To make your code work using res.download()
, you need to save the fileData
in server as a file, and then invoke res.download()
with that file's path:
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])
。
Also, please note new Buffer(string[, encoding])
is deprecated now. It is better to use Buffer.from(string[, encoding])
.
这篇关于Node Express.js-从内存下载文件-'文件名必须是字符串'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!