LukaG
LukaG

Reputation: 43

AJAX request png/jpeg image from (NodeJS + Express) server and show it in html

basically I need to receive png or jpeg image from my server, and show it inside img tag on my website.

My architecture looks like this:

Client - Server1 (my server) - Server2 (some public server)

  1. Client sends Ajax request to Server1.
  2. Server1 sends request to Server2.
  3. Server2 sends image back to Server1.
  4. Server1 sends image back to Client.

Client code:

$("#testButton").click(function() {
  $.ajax({
    method: "get",
    async: false,
    url: "/test"
  }).done(function (response){
    alert(response.imageData);
    $("#resultImage").attr("src", "data:image/png;base64," + response.imageData);
  });
});

Server1 code:

router.get('/test', function(req, res, next){
  var url = 'https://ion.gemma.feri.um.si/ion/services/geoserver/demo1/wms?service=WMS&version=1.1.0&request=GetMap&layers=demo1%3Amaribor-dof25&bbox=546631.6237364038%2C156484.86830455417%2C550631.7865026393%2C160485.0310707898&width=767&height=768&srs=EPSG%3A3794&format=image%2Fjpeg';
  request(url, function (error, response, body) {
    console.log('error:', error);
    console.log('statusCode:', response && response.statusCode);
    console.log(response.headers['content-type']);
    console.log(body);
    return res.json({ imageData: body});
  });
});

If I enter the url above directly to img src, it is shown correctly. Image is also shown correctly when I input url directly into browser.

When I receive image data back to my client from server1, data looks like this:

enter image description here

Any ideas how to fix this ?

Upvotes: 1

Views: 1210

Answers (1)

Marcos Casagrande
Marcos Casagrande

Reputation: 40374

Since you're building a base64 encoded image on the front end, the backend must return a base64 encoded image.

You are returning the image in utf8 format which of course won't work. utf8 is the default encoding when using request package.

You can use encoding property of the request package for that. Or pass encoding: null & convert body to a base64 string using .toString('base64')

request({ url, encoding: 'base64' }, function (error, response, body) {
    console.log('error:', error);
    console.log('statusCode:', response && response.statusCode);
    console.log(response.headers['content-type']);
    console.log(body);
    return res.json({ imageData: body});
});

Now response.imageData is a base64 encoded string that you can use with: data:image/png;base64,

Have in mind that you're harcoding png on the front end. If you're going to work with different extensions, you can send the full src from the server:

// 'content-type' must not be image/png or image/jpeg, improve the logic
// I'll leave that to you.
const src = `data:${response.headers['content-type']};base64,${body}`;

return res.json({ src });

Another option, is to remove the ajax, and send the image directly, without base64.

front

$("#resultImage").attr("src", "/test");

back

app.get('/test', (req, res) => {
   let url = 'https://ion.gemma.feri.um.si/ion/services/geoserver/demo1/wms?service=WMS&version=1.1.0&request=GetMap&layers=demo1%3Amaribor-dof25&bbox=546631.6237364038%2C156484.86830455417%2C550631.7865026393%2C160485.0310707898&width=767&height=768&srs=EPSG%3A3794&format=image%2Fjpeg';

   request(url).pipe(res);
});

Upvotes: 2

Related Questions