Cara memposting file dari formulir dengan Axios

130

Menggunakan HTML mentah ketika saya mengirim file ke server flask menggunakan perintah berikut, saya dapat mengakses file dari permintaan flask global:

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

Dalam labu:

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

Ketika saya mencoba melakukan hal yang sama dengan Axios, permintaan flask global kosong:

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

Jika saya menggunakan fungsi uploadFile yang sama di atas tetapi menghapus header json dari metode axios.post, saya mendapatkan kunci formulir dari objek permintaan labu saya daftar csv dari nilai string (file adalah .csv).

Bagaimana saya bisa mendapatkan objek file yang dikirim melalui axios?

Don Smythe
sumber
@Niklesh ya salah ketik potong dan tempel, saya perbaiki di atas, menyertakan tanda kutip ganda di kode.
Don Smythe
apakah Anda mencoba v-on:change="uploadFile"dengan inputalih - alih formtag?
Niklesh Raut
@ Niklesh Saya mendapatkan hasil yang sama - data dikirim sebagai string dan diambil oleh request.form bukan request.files di flask.
Don Smythe

Jawaban:

273

Tambahkan file ke formDataobjek, dan setel Content-Typeheader ke 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'
    }
})
Niklesh Raut
sumber
1
Setelah memposting file. Apakah kita perlu mengaksesnya dari permintaan HTTP atau perlu mengaksesnya dari parameter di sisi server.
Parth Patel
@ParthPatel: Saya menggunakan $_FILESuntuk mendapatkan file di sisi server karena saya menggunakan PHP
Niklesh Raut
7
Terima kasih untuk posting ini, tapi saya masih tidak mengerti mengapa kita membutuhkannya FormData. Menurut dokumen axios, keduanya Filedan FormDatadiperlakukan sebagai Browser saja , jadi kedua cara tersebut dapat dilihat secara setara ( github.com/axios/axios#request-config )
Hiroki
Hebat! Saya mengirim 'data: {data: formData}' yang menghasilkan kesalahan 412. Berhasil dengandata:formData
Aseem
3
PERHATIAN: cuplikan berfungsi sebagaimana adanya saat dijalankan dalam konteks browser. Untuk berjalan di node.js, seseorang harus meneruskan header yang dihitung oleh formData.getHeaders()Ini adalah masalah yang diketahui dengan axios; lihat misalnyahttps://github.com/axios/axios/issues/789
mjv
13

Contoh aplikasi menggunakan Vue. Membutuhkan server backend yang berjalan di localhost untuk memproses permintaan:

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

maris
sumber
bolehkah saya meminta Anda untuk melihat pertanyaan terkait aksios di sini: stackoverflow.com/questions/59470085/… ?
Istiaque Ahmed
5

Ini bekerja untuk saya, saya harap membantu seseorang.

var frm = $('#frm');
let formData = new FormData(frm[0]);
axios.post('your-url', formData)
    .then(res => {
        console.log({res});
    }).catch(err => {
        console.error({err});
    });
OCornejo
sumber
menggunakan Nuxt - ini akhirnya berhasil untuk saya. menghapus headers: { 'Content-Type': 'multipart/form-data' }adalah satu-satunya cara yang benar-benar mengirim posting setelah mendapat respon server dari opsi. Saya mungkin melakukan sesuatu yang salah, tetapi berhasil dan saya membiarkannya sendiri lol
Jeff Bluemel
Ini luar biasa! Saya tidak pernah menyangka bahwa Anda dapat mengirimkan seluruh formulir. Terima kasih!
Dara Java