147

I need to download a .jpg image from a remote server and convert it into a base64 format. I'm using axios as my HTTP client. I've tried issuing a git request to the server and checking the response.data however it doesn't seem to work like that.

Link to axios: https://github.com/mzabriskie/axios

Link to base64 implementation: https://www.npmjs.com/package/base-64

I'm using NodeJS / React so atob/btoa doesn't work, hense the library.

axios.get('http://placehold.it/32').then(response => {
    console.log(response.data); // Blank
    console.log(response.data == null); // False 
    console.log(base64.encode(response.data); // Blank
}).catch(err => console.log(err));
Hobbyist
  • 15,888
  • 9
  • 46
  • 98
  • 1
    Have you tried to change responseType to say blob? From docs "// `responseType` indicates the type of data that the server will respond with" – Yury Tarabanko Jan 25 '17 at 08:47

6 Answers6

345

This worked great for me:

function getBase64(url) {
  return axios
    .get(url, {
      responseType: 'arraybuffer'
    })
    .then(response => Buffer.from(response.data, 'binary').toString('base64'))
}
Frank
  • 1,479
  • 11
  • 15
sean-hill
  • 3,773
  • 1
  • 16
  • 13
  • 4
    This works perfectly well! I would upvote 100 times if I could! – mdev Oct 24 '18 at 14:54
  • 3
    if you're using `react-native`, add this to the top of your files: `global.Buffer = global.Buffer || require('buffer').Buffer` – ehacinom Jan 30 '19 at 20:22
  • 17
    Thank you, works great! If you're putting the base64 in – mattdedek Feb 07 '19 at 00:19
  • 5
    **DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.** – Nux Jun 25 '19 at 18:45
  • 4
    that should be Buffer.from(response.data, 'binary')) – Nux Jun 25 '19 at 18:51
  • can you imagine I spent about 5+ hours trying to find out why the file wasn't loading correctly – rotimi-best Feb 07 '21 at 17:25
  • Where can I find documentation about Buffer.from? – geschema Jul 21 '21 at 18:27
  • 1
    This can break on requests, that return something other than image (e.g. HTML page with successful status code, e.g. from redirect). A check wheather the buffer is an actual image, would be needed. – Wish Dec 06 '21 at 13:49
  • 1
    for you working with react-script v5, you must install buffer dependency first. and import it. ```npm install buffer``` – Chrisk8er Mar 04 '22 at 01:08
  • A Big Thanks to the questioner and answerer! A little thing but it saved a lot of hours of efforts. The answer should be marked as an accepted answer. – TMA Jul 11 '23 at 08:41
37

There might be a better way to do this, but I have done it like this (minus the extra bits like catch(), etc.):

axios.get(imageUrl, { responseType:"blob" })
    .then(function (response) {

        var reader = new window.FileReader();
        reader.readAsDataURL(response.data); 
        reader.onload = function() {

            var imageDataUrl = reader.result;
            imageElement.setAttribute("src", imageDataUrl);

        }
    });

I have a suspicion that at least part of your problem might be server-side. Even without setting { responseType: "blob" } you should have had something in your response.data output.

bjunc
  • 892
  • 8
  • 7
  • after searching for hours I found the solution. Thank you!! – Markus G. Feb 05 '20 at 14:45
  • Very nice, thank you. Something for others to pay attention to is needing to attach an event listener to `load`. This is essential for getting the result after reading the data into the FileReader isntance. – Erutan409 Oct 14 '22 at 19:55
25

This is what works for me (with Buffer.from) -

axios
  .get(externalUrl, {
    responseType: 'arraybuffer'
  })
  .then(response => {
    const buffer = Buffer.from(response.data, 'base64');
  })
  .catch(ex => {
    console.error(ex);
  });
Ervi B
  • 770
  • 7
  • 16
6

using responseType: "text", responseEncoding: "base64" will get response body encoded as base64 string

for example, the sample code will get base64 and write a jpg file to disk.

import axios from "axios";
import fs from "fs";

axios
  .get("https://picsum.photos/255", {
    responseType: "text",
    responseEncoding: "base64",
  })
  .then((resp) => {
    console.log(resp.data);
    fs.writeFileSync("./test.jpg", resp.data, { encoding: "base64" });
  })
Diluka W
  • 844
  • 8
  • 10
3

You can convert the blob to base64 from FileReader api and then display it.

 const fileReaderInstance = new FileReader();
 fileReaderInstance.readAsDataURL(blob); 
 fileReaderInstance.onload = () => {
 base64data = fileReaderInstance.result;                
 console.log(base64data);
 }

and display it as:

   <Image source={{uri: base64ImageData}} />
2
import { Axios } from "axios";

const axios = new Axios({});

const res = await axios.get(url, {
  responseType: "text",
  responseEncoding: "base64",
});

const base64 = Buffer.from(res.data, "base64");
edalvb
  • 581
  • 6
  • 7