我编写了一个简单的图像处理服务,它使用来自http响应流的图像上的节点gm。如果我使用nodejs的默认transfer-encoding:chunked,那么一切正常。但是,只要我尝试添加内容长度实现,nodejs就会挂起响应,或者我得到内容长度不匹配错误。
以下是有问题的代码的要点(由于示例,变量已被省略):
var image = gm(response);
// gm getter used to get origin properties of image
image.identify({bufferStream: true}, function(error, value){
this.setFormat(imageFormat)
.compress(compression)
.resize(width,height);
// instead of default transfer-encoding: chunked, calculate content-length
this.toBuffer(function(err, buffer){
console.log(buffer.length);
res.setHeader('Content-Length', buffer.length);
gm(buffer).stream(function (stError, stdout, stderr){
stdout.pipe(res);
});
});
});
这将吐出所需的图像和看起来正确的内容长度,但浏览器会挂起,表明存在一些不匹配或其他错误。我正在使用节点gm 1.9.0。
我在nodejs gm内容长度实现上看过类似的帖子,但我还没有看到有人发布这个确切的问题。
提前致谢。
答案 0 :(得分:0)
我最终改变了我的做法。我没有使用this.toBuffer(),而是使用this.write(fileName,callback)将新文件保存到磁盘,然后使用fs.createReadStream(fileName)读取它并将其传递给响应。类似的东西:
var filePath = './output/' + req.param('id') +'.' + imageFormat;
this.write(filePath, function (writeErr) {
var stat = fs.statSync(filePath);
res.writeHead(200, {
'Content-Type': 'image/' + imageFormat,
'Content-Length': stat.size
});
var readStream = fs.createReadStream(filePath);
readStream.pipe(res);
// async delete the file from filesystem
...
});
您最终会获得所需的所有标题,包括返回客户端的新内容长度。