Search code examples
javascriptbase64fileapiimage-conversion

Get base64 image from URL with Javascript


I have a snippet, that requests an image from a URL:

var toDataURL = url => fetch(url, {mode: "no-cors"})
  .then(response => response.blob())
  .then(blob => new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.onerror = reject
    reader.readAsDataURL(blob)
  }))


toDataURL('https://www.google.hu/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png')
  .then(dataUrl => {
    console.log('RESULT:', dataUrl)
  })

Code snippet is taken from this thread

This piece of code requests the google logo and it works just fine. I can see the successful image response in the network tab, I can see the image itself, also the base64 code is returned to the console as it should (you can try it by copying and pasting it to a Chrome console)

However, if I change the url to this: https://images.dog.ceo/breeds/husky/n02110185_12748.jpg

I don't get the base64 code back in the console. The request is successful, it is visible in the response, but the base64 is not returned.

I tried it with several images, with pngs most of the time it works, with jpegs never.

Are there some additional settings in the FileReader api I'm missing?


Solution

  • If you look at the images.dog.ceo/breeds/husky/n02110185_12748.jpg source, the response header does not contain Allow-Access-Control-Origin (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) .

    So from another domain you will never get this client side. However if you open the location, then open the console and paste your code, you will see that the dataURL will be logged.

    Consider white-listing domains and adding the appropriate header if possible, for some inspiration:

    Access-Control-Allow-Origin Multiple Origin Domains?