Ahora obtengo el objeto File por esta línea:
file = document.querySelector('#files > input[type="file"]').files[0]
Necesito enviar este archivo a través de json en base 64. ¿Qué debo hacer para convertirlo en una cadena base64?
Ahora obtengo el objeto File por esta línea:
file = document.querySelector('#files > input[type="file"]').files[0]
Necesito enviar este archivo a través de json en base 64. ¿Qué debo hacer para convertirlo en una cadena base64?
Respuestas:
Modo ES6 moderno (asíncrono / espera)
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:
Si quieres atrapar errores
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;
}
//...
}
Pruebe la solución usando la FileReader
clase :
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
Tenga en cuenta que .files[0]
es un File
tipo, que es una subclase de Blob
. Por lo tanto, se puede usar con FileReader
.
Vea el ejemplo de trabajo completo .
return reader.result
desde la getBase64()
función (en lugar de usar console.log(reader.result)
) porque quiero capturar la base64 como una variable (y luego enviarla a Google Apps Script). Llamé a la función con: var my_file_as_base64 = getBase64(file)
e intenté imprimir en la consola con console.log(my_file_as_base64 )
y acabo de recibir undefined
. ¿Cómo puedo asignar adecuadamente la base64 a una variable?
Si buscas una solución basada en promesas, este es el código de @ Dmitri adaptado para eso:
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)
);
A partir de las respuestas de Dmitri Pavlutin y joshua.paling, aquí hay una versión extendida que extrae el contenido base64 (elimina los metadatos al principio) y también garantiza que el relleno se realice correctamente .
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(/^.*,/, ''));
. Dado que el coma ,
está fuera del alfabeto base64, podemos quitar todo lo que aparezca hasta el coma, incluido el mismo. stackoverflow.com/a/13195218/1935128
data:
, sin ninguna coma, así que mantendré esa primera parte como está. He actualizado la respuesta en consecuencia.
La función JavaScript btoa () se puede usar para convertir datos en una cadena codificada en base64
Aquí hay un par de funciones que escribí para obtener un archivo en formato json que se puede pasar fácilmente:
//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
una función que devuelve una Promesa rechazada, la llamada no le devolverá un Error; será arrojado y tendrás que atraparlo.