Get Base64 encode file-data from Input Form
It's entirely possible in browser-side javascript.
The easy way:
The readAsDataURL() method might already encode it as base64 for you. You'll probably need to strip out the beginning stuff (up to the first ,
), but that's no biggie. This would take all the fun out though.
The hard way:
If you want to try it the hard way (or it doesn't work), look at readAsArrayBuffer()
. This will give you a Uint8Array and you can use the method specified. This is probably only useful if you want to mess with the data itself, such as manipulating image data or doing other voodoo magic before you upload.
There are two methods:
- Convert to string and use the built-in
btoa
or similar- I haven't tested all cases, but works for me- just get the char-codes
- Convert directly from a Uint8Array to base64
I recently implemented tar in the browser. As part of that process, I made my own direct Uint8Array->base64 implementation. I don't think you'll need that, but it's here if you want to take a look; it's pretty neat.
What I do now:
The code for converting to string from a Uint8Array is pretty simple (where buf is a Uint8Array):
function uint8ToString(buf) {
var i, length, out = '';
for (i = 0, length = buf.length; i < length; i += 1) {
out += String.fromCharCode(buf[i]);
}
return out;
}
From there, just do:
var base64 = btoa(uint8ToString(yourUint8Array));
Base64 will now be a base64-encoded string, and it should upload just peachy. Try this if you want to double check before pushing:
window.open("data:application/octet-stream;base64," + base64);
This will download it as a file.
Other info:
To get the data as a Uint8Array, look at the MDN docs:
- https://developer.mozilla.org/en/DOM/FileReader
My solution was use readAsBinaryString()
and btoa()
on its result.
uploadFileToServer(event) {
var file = event.srcElement.files[0];
console.log(file);
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function() {
console.log(btoa(reader.result));
};
reader.onerror = function() {
console.log('there are some problems');
};
}
I used FileReader to display image on click of the file upload button not using any Ajax requests. Following is the code hope it might help some one.
$(document).ready(function($) {
$.extend( true, jQuery.fn, {
imagePreview: function( options ){
var defaults = {};
if( options ){
$.extend( true, defaults, options );
}
$.each( this, function(){
var $this = $( this );
$this.bind( 'change', function( evt ){
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
$('#imageURL').attr('src',e.target.result);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
});
});
}
});
$( '#fileinput' ).imagePreview();
});
Inspired by @Josef's answer:
const fileToBase64 = async (file) =>
new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (e) => reject(e)
})
const file = event.srcElement.files[0];
const imageStr = await fileToBase64(file)
Complete example
Html file input
<style>
.upload-button {
background-color: grey;
}
.upload-button input{
display:none;
}
</style>
<label for="upload-photo" class="upload-button">
Upload file
<input
type="file"
id="upload-photo"
</input>
</label>
JS Handler
document.getElementById("upload-photo").addEventListener("change", function({target}){
if (target.files && target.files.length) {
try {
const uploadedImageBase64 = await convertFileToBase64(target.files[0]);
//do something with above data string
} catch() {
//handle error
}
}
})
function convertFileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = reject;
});
}