最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Responding an image (via pipe and response.end()) leads into strange behaviour - Stack Overflow

programmeradmin1浏览0评论

I used this code to pipe an image to my clients:

req.pipe(fs.createReadStream(__dirname+'/imgen/cached_images/' + link).pipe(res))

it does work but sometimes the image is not transferred pletely. But no error is thrown neither on client side (browser) nor on server side (node.js).

My second try was

var img = fs.readFileSync(__dirname+'/imgen/cached_images/' + link);
res.writeHead(200, {
  'Content-Type' : 'image/png'
});
res.end(img, 'binary');

but it leads to the same strange behaviour...

Does anyone got a clue for me?

(abstracted code...)

var http = require('http');
http.createServer(function (req, res) {
    Imgen.generateNew(
        'virtualtwins/www_leonardocampus_de/overview/28',
        'www.leonardocampus.de',
        'overview',
        '28',
        null,
        [],
        [],
        function (link) {
          fs.stat(__dirname+'/imgen/cached_images/' + link, function(err, file_info) {
                if (err) { console.log('err', err); }
                  console.log('file info', file_info.size);
                  res.writeHead(200, 'image/png');
                  fs.createReadStream(__dirname+'/imgen/cached_images/' + link).pipe(res);
              });
        }
        );
}).listen(13337, '127.0.0.1');

Imgen.generateNew just creates a new file, saves it to the disk and gives back the path (link).

I used this code to pipe an image to my clients:

req.pipe(fs.createReadStream(__dirname+'/imgen/cached_images/' + link).pipe(res))

it does work but sometimes the image is not transferred pletely. But no error is thrown neither on client side (browser) nor on server side (node.js).

My second try was

var img = fs.readFileSync(__dirname+'/imgen/cached_images/' + link);
res.writeHead(200, {
  'Content-Type' : 'image/png'
});
res.end(img, 'binary');

but it leads to the same strange behaviour...

Does anyone got a clue for me?

(abstracted code...)

var http = require('http');
http.createServer(function (req, res) {
    Imgen.generateNew(
        'virtualtwins/www_leonardocampus_de/overview/28',
        'www.leonardocampus.de',
        'overview',
        '28',
        null,
        [],
        [],
        function (link) {
          fs.stat(__dirname+'/imgen/cached_images/' + link, function(err, file_info) {
                if (err) { console.log('err', err); }
                  console.log('file info', file_info.size);
                  res.writeHead(200, 'image/png');
                  fs.createReadStream(__dirname+'/imgen/cached_images/' + link).pipe(res);
              });
        }
        );
}).listen(13337, '127.0.0.1');

Imgen.generateNew just creates a new file, saves it to the disk and gives back the path (link).

Share Improve this question edited Jan 8, 2018 at 15:13 halfer 20.4k19 gold badges109 silver badges202 bronze badges asked Jul 11, 2012 at 7:49 johannesboynejohannesboyne 2062 silver badges9 bronze badges 10
  • Is the pipe code maybe inside a callback? – Pickels Commented Jul 11, 2012 at 8:07
  • oh yes! it is... but does this effects the piping? – johannesboyne Commented Jul 11, 2012 at 8:26
  • FYI: node version: 0.8.1 – johannesboyne Commented Jul 11, 2012 at 8:30
  • @johannesboyne: Can you verify, after you get half an image, that the image on disk (i.e. generated by Imgen.generateNew) is correct? I suspect that may be your culprit... – Linus Thiel Commented Jul 11, 2012 at 8:44
  • 1 It should also be noted that res.writeHead(200, 'image/png'); is setting the header 200 to image/png. Currently your code returns Content-Type as application/octet-stream. You probably meant writeHead(200, {"Content-Type": "image/png"}); – Morgan ARR Allen Commented Jul 11, 2012 at 9:15
 |  Show 5 more ments

2 Answers 2

Reset to default 2

I've used this before and all that is needed is that in the function (req, res) {:

var path = ...; 
res.writeHead(200, {
  'Content-Type' : 'image/png'
});
fs.createReadStream(path).pipe(res);

where path is the puted path to the file to send. .pipe() will transfer the data from the read stream to the write stream and call end when the read stream ends, so there is no need to use res.end() after.

What the problem was: I had 2 different writeStreams! If WriteStream#1 is closed, the second should be closed too and then it all should be piped.

But node is asynchronous so while one has been closed, the other one hasn't. Even the stream.end() was called... well you always should wait for the close event!

发布评论

评论列表(0)

  1. 暂无评论