Sometimes you want to get things done fast and dirty, when it comes to image uploading via your web form it can take some time to create the uploader, server endpoint to handle the image then save it to a shared folder, and then serve it when needed back to the users. This is an awful lot of work that needs to be done although all you want is just to save a small icon or image.
Encoding with Base64 to the rescue
Base 64 is a way of encoding arbitrary binary data in ASCII text. It uses 4 characters per 3 bytes of data, plus it might take a bit of padding at the end. The transferred text has nothing but letters, numbers, and the symbols “+”, “/” and “=”.
Base64 can be used in a variety of contexts:
- Evolution and Thunderbird use Base64 to obfuscate e-mail passwords[1]
- Base64 can be used to transmit and store text that might otherwise cause delimiter collision
- Base64 is often used as a quick but insecure shortcut to obscure secrets without incurring the overhead of cryptographic key management
- Spammers use Base64 to evade basic anti-spamming tools, which often do not decode Base64 and therefore cannot detect keywords in encoded messages.
- Base64 is used to encode character strings in LDIF files
- Base64 is sometimes used to embed binary data in an XML file, using a syntax similar to …… e.g. Firefox’s bookmarks.html.
- Base64 is also used when communicating with government Fiscal Signature printing devices (usually, over serial or parallel ports) to minimize the delay when transferring receipt characters for signing.
- Base64 is used to encode binary files such as images within scripts, to avoid depending on external files.
- Can be used to embed raw image data into a CSS property such as a background-image.
From http://en.wikipedia.org/wiki/Base64
In the post, we will try to save some valuable time by converting the image to a string using the base64 encoding technique. First, we will add to our form a simple file uploader tag
<label for="file-input">
Upload Image
</label>
<input id="file-input" type="file" />
Notice the type of the input – file and the id file-input so we can catch the input element in our javascript code. Once we have a handle on the Input element we can register to its on-change method and listen to changes in the input
const fileInput = document.getElementById('file-input');
fileInput.onchange = (event) => {
};
Our onchange will trigger once the user selects a file to upload, we now need now to get the file and read it as a binary string
FileReader
The FileReader
object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user’s computer, using File
or Blob
objects to specify the file or data to read.
File objects may be obtained from a FileList
an object returned as a result of a user selecting files using the <input>
element, from a drag and drop operation’s DataTransfer
object, or from the mozGetAsFile()
API on an HTMLCanvasElement
. from Mozila
const file = (event.srcElement as any).files[0];
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = () => {};
reader.onerror = function() {
console.log('there are some problems');
};
};
We take the first file from the files list, and we invoke the readAsBinaryString function – reading the contents of the specified Blob
, once finished, the result
the attribute contains the raw binary data from the file as a string. That’s the reason we hook into the onload callback on the FileReader
reader.onload = () => {
const base64Str = btoa(reader.result as string);
};
Now we can treat the image as just another string
How to display the base64 image in our HTML
Now if we load the string from the backend and we wish to display it – there is no need for special magic – we only need to specify that we are using base64 encoding to the image tag. for example if the image is an SVG file:
<img src="data:image/svg+xml;base64,THE_BASE64_STRING`"
Hoping this post will save you some valuable time!
https://www.echojs.com/comment/38051/1
Two niggles…
First: The following is TypeScript, and not the current version. While I’ve actually converted a lot of the projects I’m working on to TS, prefer most training examples in plain JS, also assigning the right type to the event would probably correct the any type casting.
const file = (event.srcElement as any).files[0];
…
const base64Str = btoa(reader.result as string);
Second: There’s no mention of getting the correct mimetype and/or extension from the File interface.
Hi Tnx for the comments
As for typescript you are correct but its only mentioned in the cast phase so its not a big issue i can remove it
As for the mine type you are correct I am neglecting it since i just want to show the core concept