Nodejs发送文件作为响应
问题描述:
Expressjs框架有一个sendfile()方法。我怎么做,而不使用整个框架。我正在使用node-native-zip创建一个存档,并且我想将其发送给用户。Nodejs发送文件作为响应
答
下面是一个示例程序,它将通过从磁盘流式传输myfile.mp3(即,在发送文件之前不会将整个文件读入内存)。服务器监听端口2000
[更新]作为评价提及@Aftershock,util.pump
消失,并与称为pipe
的流原型的方法代替;下面的代码反映了这一点。
var http = require('http'),
fileSystem = require('fs'),
path = require('path');
http.createServer(function(request, response) {
var filePath = path.join(__dirname, 'myfile.mp3');
var stat = fileSystem.statSync(filePath);
response.writeHead(200, {
'Content-Type': 'audio/mpeg',
'Content-Length': stat.size
});
var readStream = fileSystem.createReadStream(filePath);
// We replaced all the event handlers with a simple call to readStream.pipe()
readStream.pipe(response);
})
.listen(2000);
从http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/
答
您需要使用流以响应发送文件(档案)拍摄的,更重要的是你有你的响应头使用适当的内容类型。
有一个例子函数,做到这一点:
const fs = require('fs');
// Where fileName is name of the file and response is Node.js Reponse.
responseFile = (fileName, response) => {
const filePath = "/path/to/archive.rar" // or any file format
// Check if file specified by the filePath exists
fs.exists(filePath, function(exists){
if (exists) {
// Content-type is very interesting part that guarantee that
// Web browser will handle response in an appropriate manner.
response.writeHead(200, {
"Content-Type": "application/octet-stream",
"Content-Disposition": "attachment; filename=" + fileName
});
fs.createReadStream(filePath).pipe(response);
} else {
response.writeHead(400, {"Content-Type": "text/plain"});
response.end("ERROR File does not exist");
}
});
}
}
在Content-Type字段的目的是描述包含在该人体完全足够的是,接收用户代理可以选择一个合适的数据代理或机制向用户呈现数据,或者以适当的方式处理数据。
“应用程序/八位字节流”在RFC 2046中定义为“任意的二进制数据”,这种内容类型的目的是为了保存到磁盘 - 什么是你真正需要的。
“文件名= [文件名]”指定将被下载的文件的名称。请参阅this stackoverflow topic。
但我没有从服务器上流式传输文件,我创建了存档文件 – andrei 2012-04-06 21:32:25
“流”我的意思是“发送文件数据到连接,因为它正在读取”,而不是“读取内存中的整个文件,然后一次发送所有数据到连接“(这是典型的天真方法)。我并不是指“将内存中的数据流到磁盘中。”我链接的帖子更详细地解释了。 – 2012-04-06 22:57:45
好吧,现在我明白了,谢谢。我会从那里开始 – andrei 2012-04-08 08:56:39