如何在不写入磁盘的情况下直接将 HTTP 响应作为 ExpressJS 响应发送

How to send HTTP response directly as ExpressJS response without writing to disk

我正在尝试使用 HTTP 模块从 URL 请求图像,然后将响应的内容直接作为我的 ExpressJS 应用给出的响应发送(不将图像请求响应写入磁盘第一的)。基本上,我想将文件从其外部 URL 下载到我的应用程序服务器的内存中,然后将其作为响应发送。

这是我目前的情况:

 var http = require('http');
 var imageUrl = 'http://vignette3.wikia.nocookie.net/clubpenguinpookie/images/d/d0/Extremely-cute-kitten_large.jpg/revision/latest?cb=20140614000321';

 var req = http.request( imageUrl  , function(response) {

    var contents = [];
    var content_length = 0;

    response.setEncoding('binary');

    response.on('data', function (chunk) {
      contents.push( chunk );
      content_length += chunk.length;
    });

    response.on('end', function() {

      res.set('Content-Type', 'image/jpeg');
      res.set('Content-Length', content_length );

      contents.forEach(function(chunk){
        res.send( chunk );
      });

      res.end();
    })

});      

req.end();

从上面可以看出,我将请求响应存储为数组中的一系列块。然后我使用 ExpressJS 响应 object 发送每个块。当我在浏览器中点击这个端点时,我得到了正确的内容类型和长度 headers 以及一些数据,但是图像没有加载并且 Firefox 告诉我它包含错误。

只需设置适当的 header(s) 并将流传输到一起。例如:

var http = require('http');
var imageUrl = 'http://vignette3.wikia.nocookie.net/clubpenguinpookie/images/d/d0/Extremely-cute-kitten_large.jpg/revision/latest?cb=20140614000321';

http.get(imageUrl, function(response) {
  if (response.statusCode !== 200) {
    res.statusCode = 500;
    return res.end();
  }

  res.set('Content-Type', 'image/jpeg');
  response.pipe(res);
});

管道更简单,确保不存在二进制数据转换问题,并且允许流背压发挥作用。