【问题标题】:nodejs gm content-length implementation hangs browsernodejs gm content-length 实现挂起浏览器
【发布时间】:2013-06-28 17:21:12
【问题描述】:

我编写了一个简单的图像处理服务,它在来自 http 响应流的图像上使用节点 gm。如果我使用 nodejs 的默认传输编码:分块,一切正常。但是,一旦我尝试添加内容长度实现,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 content-length implementation 上看到过类似的帖子,但我还没有看到有人发布这个确切的问题。

提前致谢。

【问题讨论】:

  • 建议您使用buffer.byteLength 而不是length。根本问题似乎是 Node 的 Stream 模块中的一个问题(特别是 ReadableStream),基本上是如果预期长度(所以在您的情况下为 Content-Length)长于它的实际流内容永远挂起等待额外的数据。

标签: node.js graphicsmagick content-length


【解决方案1】:

我最终改变了我的方法。我没有使用 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
  ...
});

您最终会获得所有需要的标头,包括返回给客户端的新内容长度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-20
    • 2013-02-28
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多