Come inviare un file da un modulo con Axios


129

Utilizzando HTML grezzo quando inserisco un file su un server flask utilizzando quanto segue posso accedere ai file dalla richiesta di flask globale:

<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>

In matraccio:

def post(self):
    if 'file' in request.files:
        ....

Quando provo a fare lo stesso con Axios, la richiesta del flask globale è vuota:

<form id="uploadForm" enctype="multipart/form-data" v-on:change="uploadFile">
<input type="file" id="file" name="file">
</form>

uploadFile: function (event) {
    const file = event.target.files[0]
    axios.post('upload_file', file, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
    })
}

Se utilizzo la stessa funzione uploadFile sopra ma rimuovo le intestazioni json dal metodo axios.post ottengo nella chiave del modulo del mio oggetto di richiesta flask un elenco csv di valori stringa (il file è un .csv).

Come posso ottenere un oggetto file inviato tramite axios?


@ Niklesh sì errore di battitura tagliando e incollando, l'ho corretto sopra, include le virgolette doppie nel codice.
Don Smythe

hai provato v-on:change="uploadFile"con inputinvece di formtag?
Niklesh Raut

@Niklesh ottengo lo stesso risultato: i dati inviati come stringa e raccolti da request.form non request.files in flask.
Don Smythe

Risposte:


270

Aggiungi il file a un formDataoggetto e imposta l' Content-Typeintestazione su 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'
    }
})

1
Dopo aver pubblicato i file. Abbiamo bisogno di accedervi dalla richiesta HTTP o dobbiamo accedervi dai parametri sul lato server.
Parth Patel

@ParthPatel: Sto usando $_FILESper ottenere file sul lato server poiché sto usando PHP
Niklesh Raut

7
Grazie per questo post, ma ancora non vedo perché ne abbiamo bisogno FormData. Secondo il documento di axios, sia Filee FormDatasono trattati come solo browser , quindi entrambi i modi possono essere visti allo stesso modo ( github.com/axios/axios#request-config )
Hiroki

Eccezionale ! Stavo inviando "data: {data: formData}" che generava l'errore 412. Ha funzionato condata:formData
Aseem

3
ATTENZIONE: lo snippet funziona così com'è quando viene eseguito nel contesto di un browser. Per eseguire in node.js, è necessario passare le intestazioni calcolate da formData.getHeaders()Questo è un problema noto con axios; vedi ad esempiohttps://github.com/axios/axios/issues/789
mjv

13

Applicazione di esempio che utilizza Vue. Richiede un server back-end in esecuzione su localhost per elaborare la richiesta:

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


posso chiederti di dare un'occhiata a una domanda relativa ad Axios qui: stackoverflow.com/questions/59470085/… ?
Istiaque Ahmed

5

Questo funziona per me, spero aiuti qualcuno.

var frm = $('#frm');
let formData = new FormData(frm[0]);
axios.post('your-url', formData)
    .then(res => {
        console.log({res});
    }).catch(err => {
        console.error({err});
    });

utilizzando Nuxt - questo ha finalmente funzionato per me. la rimozione headers: { 'Content-Type': 'multipart/form-data' }era l'unico modo per inviare effettivamente il messaggio dopo aver ricevuto una risposta dal server dalle opzioni. Probabilmente sto facendo qualcosa di sbagliato, ma funziona e lo lascio solo lol
Jeff Bluemel

È brillante! Non avrei mai pensato che potessi inviare l'intero modulo. Grazie!
Dara Java
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.