-->

Problems serving a binary image passed through std

2019-04-15 19:58发布

问题:

I'm attempting to create a node server that serves up a png image generated using the node-wkhtml module (basically just a wrapper for the wkhtmltoimage/wkhtmltopdf command line utility). Here's what I have so far:

var http = require('http');
var Image = require("node-wkhtml").image();

http.createServer(function (request, response) {
  new Image({ url: "www.google.com" }).convert (function (err, stdout) {
    //var theImage = new Buffer (stdout, 'binary');
    response.writeHead(200, {'Content-Type' : 'image/png',
                           'Content-Length' : stdout.length
    });
    response.write (stdout, 'binary');
    response.end ();
    //write out an error, if there is one
    if (err)
      console.log (err);
  });
}).listen(8124);

Basically, the module calls the command:

wkhtmltoimage www.google.com -

which then generates a png image and writes it to the stdout. The amount of data served seems to be correct, but I can't get the browser to display it (nor does it work if I download it as a file). I tried the following command:

wkhtmltoimage www.google.com - > download.png

and sure enough, download.png was created and contained a snapshot of the google homepage, meaning that the wkhtmltoimage utility is working correctly, and the command works. I'm a beginner at node, so I'm not super familiar how to serve up a binary file like this, can anyone see any glaring issues? Here's the node module code that works the magic:

Image.prototype.convert = function(callback) {    
  exec(util.buildCommand(this), {encoding: 'binary', maxBuffer: 10*1024*1024}, callback);
}

(the buildCommand function just generates the "wkhtmltoimage www.google.com -" command, and I've verified it does this correctly, using node inspector.

UPDATE: In case anyone finds this later and is interested, I found the solution. The plugin I was using (node-wkhtml) was not properly handling large buffers, due to the choice of using child-process.exec I changed the plugin code to use child-process.spawn instead, and it worked as desired.