节点快速.js - 从内存下载文件 - 'filename must be a string'



我正在尝试将内存中的数据打包到文本文件中并将其发送给用户,从而触发文件下载。

我有以下代码:

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 的文件名参数必须是字符串。 文件名肯定是一个字符串,所以我不确定发生了什么。

更新:

多亏了@jfriend00的建议,将 Buffer 作为文件直接发送到客户端更好、更有效,而不是先将其保存在服务器磁盘中。

为了实现,可以使用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(response);
});

根据Express文档,res.download()API是:

res.download(path [, filename] [, fn])

将路径中的文件作为"附件"传输。通常,浏览器会提示用户下载。默认情况下,内容处置标头"filename="参数是路径(这通常显示在浏览器对话框中)。使用文件名参数覆盖此默认值。

请注意,res.download()的第一个参数是"路径",它表示服务器中要下载的文件的路径。在你的代码中,第一个参数是一个缓冲区,这就是为什么 Node.js抱怨"文件名参数必须是字符串"——默认情况下,Content-Disposition头"filename="参数是path

若要使代码使用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]).

app.get('/download', (request, response) => {
const fileData = 'SGVsbG8sIFdvcmxkIQ=='
const fileName = 'hello_world.txt'
const fileType = 'text/plain'
response.writeHead(200, {
'Content-Disposition': `attachment; filename="${fileName}"`,
'Content-Type': fileType,
})
const download = Buffer.from(fileData, 'base64')
response.end(download)
})

我通过谷歌找到了这个问题。我的问题是,我想直接从内存发送生成的index.html文件,而不是先将其写入文件系统。

这是它的工作原理:

app.get('/', function (req, res) {
//set the appropriate HTTP header
res.setHeader('Content-Type', 'text/html');
//send it to the client
res.send('<h1>This is the response</h1>');
});

来源:https://stackoverflow.com/a/55032538

相关内容

最新更新