11

There is the following code:

console.log(blob);
var reader = new window.FileReader();
reader.onloadend = function() {            
  console.log(reader.result);
};
reader.readAsDataURL(blob);

blob is 'blob:http://localhost:3000/e3c23a22-75b1-4b83-b39a-75104d1909b9' and I've got the following error:

TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.

How can I fix this error and convert Blob to Base64 encoded image? Thanks in advance!

3
  • Hey Buddy, I stuck with same problem. Did you find out iDEA about it or any other way. Commented Aug 18, 2017 at 9:52
  • any update on this issue
    – Mohan Gopi
    Commented Apr 26, 2018 at 15:31
  • Your code worked for me. Thanks
    – s4tr2
    Commented Aug 30, 2018 at 10:34

5 Answers 5

7

I know this is an old question, but I came across this problem lately and it took me a while to fix it. So I am going to answer the question in case anyone run into it again.

First, I think the naming of variable blob is very confusing. Blob URLs and Blob Object are different things. This answer does a very good job explaining what a Blob URL is. I think you should rename it as below.

var blobUrl = 'blob:http://localhost:3000/e3c2...'

Then, the function readAsDataURL of FileReader requires a Blob Object as its parameter. And what you give it is the variable blob, which is a Blob URL.

So what you need to do is:

  1. Recover the Blob Object that is used to create the Blob URL
  2. Use readAsDataURL to convert the recovered Blob Object to base64 url

Here is the code I find in this answer:

var blob = new Blob(["Hello, world!"], { type: 'text/plain' });
var blobUrl = URL.createObjectURL(blob);

var xhr = new XMLHttpRequest;
xhr.responseType = 'blob';

xhr.onload = function() {
   var recoveredBlob = xhr.response;

   var reader = new FileReader;

   reader.onload = function() {
     var blobAsDataUrl = reader.result;
     window.location = blobAsDataUrl;
   };

   reader.readAsDataURL(recoveredBlob);
};

xhr.open('GET', blobUrl);
xhr.send();

1

Simply just use fetch api:

const blob = await fetch(blobUrl).then(res => res.blob())
0

You need to pass in the whole file object from the uploader and not just the blob url. By the whole file object i mean the name, type, url, etc.

Basically if the uploader has a file in the array, i.e files[0], you would pass in readAsDataURL(files[0]).

-1

Sun Haoran's answer was fantastic, lead me in the right direction to better understanding and worked like a charm.
Below I will share what I did in Angular 11, based off Sun Haoran's answer. What I needed to achieve was doing the operation within a promise and maintaining scope when completed for TypeScript:

private blobUrlToBase64(blobUrl: string): Promise<string> {
  return new Promise<string>((resolve, reject) => {
    const reader = new FileReader();
    const xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';

    xhr.onload = function () {
      reader.readAsDataURL(xhr.response);
      reader.onloadend = function () { resolve(reader.result as string); }
      reader.onerror = function (ev) { reject(`Exception reading Blob > xhr.response: ${xhr.response}\nLast Progress Event: ${ev}`); };
    };
    xhr.onerror = function (ev) { reject(`Exception fetching Blob > BlobUrl: ${blobUrl}\nLast Progress Event: ${ev}`); };

    xhr.open('GET', blobUrl);
    xhr.send();
  });
}
2
  • the answer to a javascript question should be answered with javascript...
    – Endless
    Commented Jan 9, 2022 at 16:58
  • Yes, you're right, and Sun Haoran's answer is working for javascript. However, as I stated in my answer "What I needed to achieve was doing the operation within a promise and maintaining scope when completed for TypeScript". I stated this for a reason, Endless. People of the internet will arrive at this question for both JS and TS, having both solutions available will hopefully be of use to them. But strictly speaking, you're right. Commented Jan 10, 2022 at 8:37
-3

Don't have your code about the xhr here but it's probably that you're not setting responseType right. Try xhr.responseType = 'blob' before xhr.send().

Also, apart from using FileReader, the following may be more straight forward:

xhr.onreadystatechange = function(){
    if (this.readyState == 4 && this.status == 200){
        var url = window.URL || window.webkitURL;
        img.src = url.createObjectURL(this.response);
    }
}
1
  • What? That was not what was asked. They are clearly using something like a video stream and want to turn the blob url into base64 to use elsewhere. Commented Aug 30, 2016 at 15:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.