August 27, 2020
  • Engineering
  • JavaScript

Converting a base64 string to a blob in JavaScript

Matt Netkow

base64-to-blob

Web browsers provide a variety of data primitives that web developers use to manage, manipulate, and store data – from plain text, to files, images, videos and more. However, using them correctly and effectively can be confusing. One such example is converting a base64 string to a blob using JavaScript. A blob represents binary data in the form of files, such as images or video. Suppose you have an image in string format that needs to be uploaded to a server. However, the available API accepts the image in blob format only. What do you do?

According to various solutions around the Internet, conversion appears to be complex. Manipulating byte arrays? No thanks. Fortunately, there’s an easier, modern approach available thanks to the Fetch API. It’s a powerful feature built into all web browsers that is commonly used to fetch resources across the network, like making HTTP requests to your backend APIs.

Fetch returns a Response object. As it turns out, it can convert data into more than just JSON, it can also return array buffers, form data, and blobs. In this case, we’ll use blobs.

Easy as one, two

First, pass a base64 string to fetch:

const base64Data = "aGV5IHRoZXJl";
const base64 = await fetch(base64Data);

Depending on the format of the base64 string, you might need to prepend content type data. For example, a JPEG image:

const base64Response = await fetch(`data:image/jpeg;base64,${base64Data}`);

Next, convert the response to a blob:

const blob = await base64Response.blob();

That’s it! From here, you can upload it to a server, display it on the screen, and more.

Bonus: Converting a blob to a base64 string

What about reversing the conversion, from a blob to a base64 string? Unfortunately, this is a bit more complicated (though if you know of a better approach, let me know in the comments!).

I encountered this real-world example recently while building a feature for the Ionifits demo app. While entering a company expense, users take a photo of the expense receipt. To implement this, I used the Capacitor Camera and Filesystem APIs.

After taking a photo, the Camera API returns a blob URL, which looks like:

https://myapp.com/cc7622aa-271b-4ee3-b707-28cbc84bc37a

To save the photo permanently to the filesystem (blobs are objects temporarily loaded into browser memory), the Filesystem API requires the data to be in base64 format, so we must convert the blob into a base64 string.

There are a variety of techniques to do so, but as a fan of asynchronous programming, I recommend creating a Promise then using the FileReader API to convert the blob:

convertBlobToBase64 = (blob) => new Promise((resolve, reject) => {
    const reader = new FileReader;
    reader.onerror = reject;
    reader.onload = () => {
        resolve(reader.result);
    };
    reader.readAsDataURL(blob);
});

const base64String = await convertBlobToBase64(blob);

Voilà! Using modern web development techniques, converting blobs and base64 strings back and forth isn’t so scary after all. What other tips or tricks have you picked up recently in your web development journey?

Special thanks to Capacitor community member Matt Wyld for his feedback, especially performance testing the Fetch approach on mobile.


Matt Netkow