0

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 content-length 実装に関する同様の投稿を見たことがありますが、この正確な問題を投稿した人はまだ見たことがありません。

前もって感謝します。

4

1 に答える 1

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
  ...
});

クライアントに返す新しい content-length を含む、必要なすべてのヘッダーを取得することになります。

于 2013-07-31T19:22:37.877 に答える