Estoy tratando de implementar el envío de formularios ajax personalizados usando jQuery
. En resumen, hace algo como esto:
Funciona bien con entradas y selecciones simples, pero los problemas comienzan cuando intento enviar archivos. Decidí implementar una función que lee el contenido del archivo como Blob
y lo transforma en String
en Base64 y crea un objeto para un archivo que se procesará en el lado del servidor, por lo que la estructura de mi formulario de carga podría verse así:
{ name: 'John', surname: 'Doe', roles: ['CLIENT', 'ADMIN'], photo: { fileName: 'photo.jpg', mimeType: 'image/jpeg' content: '%base64_encoded_String%' } }
Estaba investigando FileReader
para trabajar con el contenido del archivo y he escrito algo como esto:
function fileToBase64( file ) { let reader = new FileReader() let fileContent reader.onload = function() { fileContent = reader.result } reader.readAsDataURL( file ) return { fileName: file.name, mimeType: file.type, content: fileContent } }
Sin embargo, al no tener tanta experiencia con javascript, no puedo entender las promesas: resulta que lo que sucede mientras leo un File
sucede después de que devuelvo el objeto, por lo tanto, el contenido no está undefined
. ¿Cómo puedo asegurarme de que el archivo se lea antes de que ocurra la devolución? Vi una solución FileReaderSync
pero parece que ahora se eliminó de los navegadores.
Básicamente, mi código para obtener valores de campo se llama dentro de una función $( 'form' ).on( 'submit' )
y se ve así:
let fieldIds = someFunctionThatGetsIdsForForm() fieldIds.map( id => { let field = $( '#' + id ) let isFileInput = field.is( 'input' ) && field.attr( 'type' ) === 'file' let name = field.attr( 'name' ) // process value according to input type if ( isFileInput ) { let files = field[0].files let fileDatas = [] // process all files from this input for (let i = 0; i < files.length; i++) { let file = files.item(i) fileDatas.push( fileToBase64( file ) ) // how do I wait for this to complete before going further? } output[name] = fileDatas.length === 1 ? fileDatas[0] : fileDatas // either a single file or multiple } else { output[name] = field.val() } } )
Se agradece cualquier información sobre la espera de procesos asincrónicos como la lectura.