Estoy tratando de crear una carga de archivos usando matraz y formularios, pero no funciona del todo. No puedo entender dónde está el problema. Intenté seguir varios tutoriales y miré muchos hilos de desbordamiento de pila sin éxito.
Parece que Flask no recibe ningún dato de formulario y no puedo entender por qué. Aquí está mi código python para el punto final de carga:
@app.route("/upload", methods=["post"]) def upload_endpoint(): # Just prints ImmutableMultiDict([]) twice print(request.form) print(request.files) return "Success", 200Y aquí está mi js relacionado con el proceso de carga:
// Creates and returns an input element with all needed tags and event listeners function createInput() { const input = document.createElement("input") input.setAttribute("type", "file") input.setAttribute("multiple", "true") input.setAttribute("name", "file") input.addEventListener("change", () => { submitInput(input) }, false) return input } // Takes an input tag, puts it in a form, and submits it via xhr function submitInput(input) { const form = document.createElement("form") form.appendChild(input) const xhr = new XMLHttpRequest() xhr.open("POST", "/upload") // Calculates and logs upload progress xhr.upload.addEventListener("progress", (e) => { const percent = e.lengthComputable ? (e.loaded / e.total) * 100 : 0 console.log(percent.toFixed(2)) }) xhr.setRequestHeader("Content-Type", "multipart/form-data") xhr.send(new FormData(form)) } // Handles for when element is clicked. .click() is used to create the popup dialogue for selecting a fike centerDrop.addEventListener("click", () => { const input = createInput() input.click() return false }, false) // Handles for when a file is dropped into the browser dropArea.addEventListener("drop", (e) => { const input = createInput() input.files = e.dataTransfer.files submitInput(input) }, false)He estado probando la función de carga con una imagen de 200 kb, sin embargo, las solicitudes que se crean tienen un tamaño <1 kb según la consola de desarrollo en el navegador. ¿Por qué parece que la imagen no está incluida en la solicitud?
En lugar de agregar toda la entrada mediante programación en el formulario, intente agregar solo sus archivos:
function submitInput(input) { ... form.append("file", input.files) // Instead of form.appendChild(input) ... }Y luego acceda a él en el BE usando:
print("files:", request.files['file'])El problema es que estaba tratando de manejar la configuración de los encabezados de solicitud yo mismo. Simplemente eliminar esta línea: xhr.setRequestHeader("Content-Type", "multipart/form-data") me funcionó.
La moraleja de la historia es dejar que XMLHttpRequest maneje los encabezados por usted, ya sabe lo que está haciendo en el caso de enviar datos de formulario.