Búsqueda de sitios web

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});
    });

Artículos relacionados