No tengo ningún problema para obtener la URL firmada, y el archivo se está cargando en S3, pero cuando descargo el archivo no puedo abrirlo. He probado PDF y archivos de imagen.
Obtengo el archivo así, donde 'e' es el evento de carga del archivo desde la entrada del archivo del navegador:
let fileData = e.target.files[0]; let reader = new FileReader(); reader.readAsBinaryString(fileData); // generates a binary representation of the image reader.onload = function(e) { let bits = e.target.result; let data = { originalFilename: fileData.name, filename: fileData.name, mimeType: fileData.type, fileSizeBytes: fileData.size, lastModified: fileData.lastModified, bin: bits }; }Guardo el json de 'datos' en IndexeddB y luego, cuando el navegador está en línea, obtengo una URL firmada e intento cargarla de esta manera:
// signedUrl is the signed URL // data is the saved file data from the IndexeddB (above) let contentType = data.mimeType let binaryString = data.bin; // bin is a binary string let formData = new FormData(); formData.append("file", btoa(data.bin)); // upload the file directly to AWS return $.ajax({ url: signedUrl, method: "POST", contentType: contentType , data: formData, processData: false }) .then(function (response) { console.log(response); }) .catch(function (e) { console.log('Error in file upload to AWS:'); console.log(e); throw('Upload failed'); })Hay muchos ejemplos que muestran cómo publicar el archivo en la URL firmada si tiene el objeto File (o está usando Postman), pero mi aplicación web permite a los usuarios "cargar" archivos sin conexión y se almacenan en IndexeddB como cadenas binarias. Todo esto funciona bien, y puedo publicar fácilmente los archivos en mi servidor, recrear el archivo y luego enviarlos a S3, pero quiero evitar los viajes adicionales.
He intentado crear un Blob y algunas otras cosas y estoy atascado. Cualquier ayuda sería muy apreciada.
Realmente, todo lo que necesito saber es "¿Exactamente qué formato es el archivo que se publica en la URL firmada en los datos de la publicación y cómo puedo convertir los datos de mi archivo a ese formato?"
OK, finalmente descubrí exactamente qué hacer. Hay muy poca documentación en el sitio de Amazon y mucha información errónea en la web. Solo tiene que volver a crear el archivo Blob (y NO use fileData):
// signedUrl is the signed URL // data is the saved file data from the IndexeddB (above) let contentType = data.mimeType let binaryString = data.bin; // bin is a binary string // rebuild the file object as a Blob to send to Amazon let bytes = new Uint8Array(binaryString.length); for (let i=0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } let file = new Blob([bytes], {type: contentType}); // upload the file directly to AWS return $.ajax({ url: signedUrl, method: "POST", contentType: false, data: file, processData: false }) .then(function (response) { console.log(response); }) .catch(function (e) { console.log('Error in file upload to AWS:'); console.log(e); throw('Upload failed'); })