简体   繁体   中英

Nodejs serve base64 as Image

I am trying to serve a base64 string as an image with image/png headers. The headers are being set properly but the images are not being shown all I can see is a blank screen. here is the code:

request('someCustomLink', function (error, response, body) {
// someCustomLink gives the base64 string
        var img = new Buffer(body, 'base64');
        res.writeHead(200, {
            'Content-Type': 'image/png',
            'Content-Length': img.length
        });
        res.end(img);         
});

this is the link that I followed to arrive at this solution.

Any help will be appreciated.

EDIT Here are the response headers from my someCustomLink (it might help in understanding the problem betr)

Accept-Ranges:bytes
Content-Length:128778
Content-Type:image-jpeg
Date:Thu, 21 Dec 2017 06:03:52 GMT
ETag:"edc04d469779108860478b361b7427d7"
Last-Modified:Mon, 11 Dec 2017 08:54:32 GMT
Server:AmazonS3
x-amz-id-2:QlR39g0vC5CeOo6fdKzX9uFB+uiOtj61c0LKW2rQLcCPWllcKyfbpg93Yido+vZfzMzB3lmhbNQ=
x-amz-request-id:3EC77634D9A05371

This is the get req

var request = require('request').defaults({ encoding: null });

app.get('/thumb/:thumbLink', function(req, res) {


        request('https://s3.amazonaws.com/my-trybucket/projectImages/'+req.params.thumbLink, function (error, response, body) {
            //console.log('error:', error); // Print the error if one occurred
            //console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
            //console.log('body:', body); // Print the HTML for the Google homepage.
            var img = new Buffer(body, 'base64');
            res.writeHead(200, {
                'Content-Type': 'image/png'

            });
            res.end(img);
        });
    });

-Thanks

The response that you are getting contains data:image/png;base64, . You have remove this before creating the Buffer . See example below

request('https://s3.amazonaws.com/my-trybucket/projectImages/e31492f7314837a22a64395eee7cedfd', function(error, response, body) {
    var img = new Buffer(body.split(',')[1], 'base64');
    res.writeHead(200, {
      'Content-Type': 'image/png',
      'Content-Length': img.length 
    });
    res.end(img);
})

Was stuck for long on this particular issue too only to find out that sending the actual data Body that comes back from s3 is actually sufficient to display the image. Here's my implementation (in typescript):

// a method in my Bucket class

async getObject(key: string) {
    const params = {
      Bucket: this.bucket, //my bucket name set in my constructor
      Key: key,
    };
    return new Promise((resolve, reject) => {
      s3.getObject(params, (err, data) => {
        if (err) reject(err);
        if(data) resolve(data.Body);
      });
    });
  }

// the get request route

app.get(
  "url/:folder/:id",
  async (req: Request, res: Response) => {
    const { folder, id } = req.params;
    const image = (await new Bucket().getObject(`${folder}/${id}`)) as Buffer;
    res.send(image);
  }
);

I got the error ECONNRESET on my server. It turned out that res.end() was responsible for it. I replaced it with res.send() and the transfer went without problems. Here is my generic solution for serving base64 files

async (req: Request, res: Response) => {
  const { id } = req.params;

  //Get the image or file with your own method
  const base64File = await GetBase64File(id)

  const [fileInfo, fileData] = base64File.split(",");
  const contentType = fileInfo.split(";")[0].replace("data:", "");

  res.setHeader("Content-Type", contentType);
  res.setHeader("Content-Length", fileData.length);

  const buffer = Buffer.from(fileData, "base64");
  res.send(buffer);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM