javascript - Cómo enviar un archivo desde un formulario con Axios
Usando HTML sin procesar cuando publico un archivo en un servidor Flask usando lo siguiente, puedo acceder a archivos desde el global de la solicitud de Flask:
<form id="uploadForm" action='upload_file' role="form" method="post" enctype=multipart/form-data>
<input type="file" id="file" name="file">
<input type=submit value=Upload>
</form>
En el frasco:
def post(self):
if 'file' in request.files:
# ....
Cuando intento hacer lo mismo con Axios, el objeto global de la solicitud de Flask está vacío:
<form id="uploadForm" enctype="multipart/form-data" v-on:change="uploadFile">
<input type="file" id="file" name="file">
</form>
<script>
function uploadFile(event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
</script>
Si utilizo la misma función uploadFile anterior pero elimino los encabezados json del método axios.post, obtengo en la clave form de mi objeto de solicitud de Flask una lista CSV de valores de cadena (el archivo es un .csv).
¿Cómo puedo obtener un objeto de archivo enviado vía axios?
Respuesta #1
Agrega el archivo a un objeto formData, y establece el encabezado Content-Type en multipart/form-data.
var formData = new FormData();
var imagefile = document.querySelector('#file');
formData.append("image", imagefile.files[0]);
axios.post('upload_file', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
Respuesta #2
Aplicación de ejemplo usando Vue. Requiere un servidor backend ejecutándose en localhost para procesar la solicitud:
var app = new Vue({
el: "#app",
data: {
file: ''
},
methods: {
submitFile() {
let formData = new FormData();
formData.append('file', this.file);
console.log('>> formData >> ', formData);
// You should have a server side REST API
axios.post('http://localhost:8080/restapi/fileupload',
formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}
).then(function () {
console.log('SUCCESS!!');
})
.catch(function () {
console.log('FAILURE!!');
});
},
handleFileUpload() {
this.file = this.$refs.file.files[0];
console.log('>>>> 1st element in files array >>>> ', this.file);
}
}
});
https://codepen.io/pmarimuthu/pen/MqqaOE
Respuesta #3
Si no quieres usar un objeto FormData (por ejemplo, tu API acepta firmas de tipo de contenido específicas y multipart/formdata no es una de ellas), entonces puedes hacer esto en su lugar:
uploadFile: function (event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': file.type
}
})
}
Respuesta #4
Compartiendo mi experiencia con React y el input de HTML
Definir campo de entrada
<input type="file" onChange={onChange} accept ="image/*"/>
Definir un listener onChange
const onChange = (e) => {
let url = "https://<server-url>/api/upload";
let file = e.target.files[0];
uploadFile(url, file);
};
const uploadFile = (url, file) => {
let formData = new FormData();
formData.append("file", file);
axios.post(url, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
}).then((response) => {
fnSuccess(response);
}).catch((error) => {
fnFail(error);
});
};
const fnSuccess = (response) => {
//Add success handling
};
const fnFail = (error) => {
//Add failed handling
};
Respuesta #5
Esto funciona para mí, espero que ayude a alguien.
var frm = $('#frm');
let formData = new FormData(frm[0]);
axios.post('your-url', formData)
.then(res => {
console.log({res});
}).catch(err => {
console.error({err});
});
