Respostas:
Maneira ES6 moderna (assíncrona / aguardar)
const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
async function Main() {
const file = document.querySelector('#myfile').files[0];
console.log(await toBase64(file));
}
Main();
UPD:
Se você deseja pegar erros
async function Main() {
const file = document.querySelector('#myfile').files[0];
const result = await toBase64(file).catch(e => Error(e));
if(result instanceof Error) {
console.log('Error: ', result.message);
return;
}
//...
}
Experimente a solução usando a FileReader
classe :
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
var file = document.querySelector('#files > input[type="file"]').files[0];
getBase64(file); // prints the base64 string
Observe que esse .files[0]
é um File
tipo, que é uma subcategoria de Blob
. Assim, pode ser usado com FileReader
.
Veja o exemplo de trabalho completo .
return reader.result
a getBase64()
função (em vez de usar console.log(reader.result)
) porque quero capturar a base64 como uma variável (e enviá-la ao script do Google Apps). Chamei a função com: var my_file_as_base64 = getBase64(file)
e tentei imprimir no console console.log(my_file_as_base64 )
e acabei de receber undefined
. Como atribuir corretamente a base64 a uma variável?
Se você procura uma solução baseada em promessas, este é o código do @ Dmitri adaptado para isso:
function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
var file = document.querySelector('#files > input[type="file"]').files[0];
getBase64(file).then(
data => console.log(data)
);
Com base nas respostas Dmitri Pavlutin e joshua.paling, aqui está uma versão estendida que extrai o conteúdo base64 (remove os metadados no início) e também garante que o preenchimento seja feito corretamente .
function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
let encoded = reader.result.toString().replace(/^data:(.*,)?/, '');
if ((encoded.length % 4) > 0) {
encoded += '='.repeat(4 - (encoded.length % 4));
}
resolve(encoded);
};
reader.onerror = error => reject(error);
});
}
resolve(reader.result.replace(/^.*,/, ''));
. Como o coma ,
está fora do alfabeto base64, podemos remover qualquer coisa que surja até e incluindo o coma. stackoverflow.com/a/13195218/1935128
data:
, sem vírgula, por isso vou manter a primeira parte como está. Atualizei a resposta de acordo.
A função JavaScript btoa () pode ser usada para converter dados em string codificada em base64
Aqui estão algumas funções que escrevi para obter um arquivo em um formato json que pode ser transmitido facilmente:
//takes an array of JavaScript File objects
function getFiles(files) {
return Promise.all(files.map(file => getFile(file)));
}
//take a single JavaScript File object
function getFile(file) {
var reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onerror = () => { reader.abort(); reject(new Error("Error parsing file"));}
reader.onload = function () {
//This will result in an array that will be recognized by C#.NET WebApi as a byte[]
let bytes = Array.from(new Uint8Array(this.result));
//if you want the base64encoded file you would use the below line:
let base64StringFile = btoa(bytes.map((item) => String.fromCharCode(item)).join(""));
//Resolve the promise with your custom file structure
resolve({
bytes: bytes,
base64StringFile: base64StringFile,
fileName: file.name,
fileType: file.type
});
}
reader.readAsArrayBuffer(file);
});
}
//using the functions with your file:
file = document.querySelector('#files > input[type="file"]').files[0]
getFile(file).then((customJsonFile) => {
//customJsonFile is your newly constructed file.
console.log(customJsonFile);
});
//if you are in an environment where async/await is supported
files = document.querySelector('#files > input[type="file"]').files
let customJsonFiles = await getFiles(files);
//customJsonFiles is an array of your custom files
console.log(customJsonFiles);
onInputChange(evt) {
var tgt = evt.target || window.event.srcElement,
files = tgt.files;
if (FileReader && files && files.length) {
var fr = new FileReader();
fr.onload = function () {
var base64 = fr.result;
debugger;
}
fr.readAsDataURL(files[0]);
}
}
await
uma função que retorna uma Promessa rejeitada, você não receberá um Erro retornado pela chamada; será lançado e você precisará pegá-lo.