我的任务是读取NodeJ中的jpeg文件并将其作为http响应发送以回答服务器请求。似乎是微不足道的。但是,我的第一个解决方案失败浏览器确实收到了一些二进制文件,比原始文件大30%。
我的代码是(简化; res是SeverResponse类型):
...
var fs = require('fs');
var stream = fs.createReadStream(pathToJPEG, {encoding: 'binary'});
res.setHeader('Content-Type', "image/jpeg");
stream.pipe(res);
...
事实证明,到达浏览器的是源数据的UTF-8编码版本。我也能够将响应对象排除在罪魁祸首之外。当我给它一个替代流(来自缓冲区,而不是文件)时,它运行得很好。
原来解决我的问题的方法是删除选项{encoding:' binary'}。我的浏览器收到了正确的图片:
...
var fs = require('fs');
var stream = fs.createReadStream(pathToJPEG);
res.setHeader('Content-Type', "image/jpeg");
stream.pipe(res);
...
我的问题是:为什么?
看起来很直观,第一个非工作版本应该是正确的版本,因为它明确声明了如何读取文件。
答案 0 :(得分:3)
这是因为binary
编码实际上不是binary
。 createReadStream
使用Buffer接受的相同encoding
个参数。来自Node Buffer Docs:
'binary' - 一种将缓冲区编码为单字节(即latin-1)编码字符串的方法。不支持字符串'latin-1'。而只是简单地传递'二进制'来使用'latin-1'编码。
只需将编码设置为null
即可获取原始流或缓冲区,或者根本不像第二个示例中那样指定任何内容。
答案 1 :(得分:0)
Ixe是正确的,将编码更改为null可行,但仅在升级到较新的node / express程序包之后。这是我的代码,可以正确上传tar文件:
fs.exists(filePath, function(exists){
if (exists) {
var stat = fs.statSync(filePath);
console.log('sending file, size %d', stat.size);
res.writeHead(200, {
"Content-Type": "application/x-tar",
"Content-Disposition": "attachment; filename=" + filePath,
"Content-Length": stat.size,
"Content-Transfer-Encoding": "binary"
});
fs.createReadStream(filePath, { encoding: null }).pipe(res); //must set encoding to null, as binary is not treated correctly
} else {
console.log('file not exist.');
res.writeHead(400, {"Content-Type": "text/plain"});
res.end("ERROR File does not exist");
}
});