วิธีโพสต์ไฟล์จากแบบฟอร์มด้วย Axios


130

การใช้ HTML ดิบเมื่อฉันโพสต์ไฟล์ไปยังเซิร์ฟเวอร์ flask โดยใช้สิ่งต่อไปนี้ฉันสามารถเข้าถึงไฟล์จากคำขอ 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>

ในขวด:

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

เมื่อฉันพยายามทำเช่นเดียวกันกับ Axios คำขอ flask global ว่างเปล่า:

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

ถ้าฉันใช้ฟังก์ชัน uploadFile เดียวกันด้านบน แต่ลบส่วนหัว json ออกจากเมธอด axios.post ฉันจะได้รับคีย์ฟอร์มของอ็อบเจ็กต์คำขอขวดของฉันรายการ csv ของค่าสตริง (ไฟล์คือ. csv)

ฉันจะรับออบเจ็กต์ไฟล์ที่ส่งผ่าน axios ได้อย่างไร


@Niklesh ใช่การตัดและวางพิมพ์ผิดฉันแก้ไขด้านบนรวมถึงเครื่องหมายคำพูดคู่ในรหัส
Don Smythe

คุณได้ลองv-on:change="uploadFile"ใช้inputแทนformแท็กหรือไม่?
Niklesh Raut

@Niklesh ฉันได้ผลลัพธ์เดียวกัน - ข้อมูลที่ส่งเป็นสตริงและรับโดย request.form ไม่ใช่ request.files ในขวด
Don Smythe

คำตอบ:


273

เพิ่มไฟล์ไปยังformDataวัตถุและการตั้งค่าส่วนหัวContent-Typemultipart/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
หลังจากโพสต์ไฟล์ เราจำเป็นต้องเข้าถึงจากคำร้องขอ HTTP หรือต้องการเข้าถึงจากพารามิเตอร์ทางฝั่งเซิร์ฟเวอร์
Parth Patel

@ParthPatel: ฉันใช้$_FILESเพื่อรับไฟล์ในฝั่งเซิร์ฟเวอร์ขณะที่ฉันใช้ PHP
Niklesh Raut

7
ขอบคุณสำหรับการโพสต์นี้ FormDataแต่ผมก็ยังไม่เห็นว่าทำไมเราต้อง ตามเอกสารของ axios ทั้งสองFileและFormDataถือว่าเป็น เบราว์เซอร์เท่านั้นดังนั้นทั้งสองวิธีจึงสามารถมองเห็นได้อย่างเท่าเทียมกัน ( github.com/axios/axios#request-config )
Hiroki

สุดยอด! ฉันกำลังส่ง 'data: {data: formData}' ซึ่งสร้างข้อผิดพลาด 412 มันใช้ได้กับdata:formData
Aseem

3
ความสนใจ: ข้อมูลโค้ดทำงานตามที่เป็นอยู่เมื่อเรียกใช้ในบริบทของเบราว์เซอร์ ในการรันใน node.js เราจำเป็นต้องส่งผ่านส่วนหัวที่คำนวณโดยformData.getHeaders()นี่เป็นปัญหาที่ทราบเกี่ยวกับ axios ดูเช่นhttps://github.com/axios/axios/issues/789
mjv

13

ตัวอย่างแอปพลิเคชันโดยใช้ Vue ต้องใช้เซิร์ฟเวอร์แบ็กเอนด์ที่รันบน localhost เพื่อดำเนินการตามคำขอ:

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


ฉันขอให้คุณดูคำถามที่เกี่ยวข้องกับ axios ได้ที่นี่: stackoverflow.com/questions/59470085/… ?
Istiaque Ahmed

5

สิ่งนี้ได้ผลสำหรับฉันฉันหวังว่าจะช่วยให้ใครบางคน

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

การใช้ Nuxt - ในที่สุดสิ่งนี้ก็ได้ผลสำหรับฉัน การลบheaders: { 'Content-Type': 'multipart/form-data' }เป็นวิธีเดียวที่จะส่งโพสต์หลังจากได้รับการตอบกลับจากเซิร์ฟเวอร์จากตัวเลือก ฉันอาจจะทำอะไรผิดพลาด แต่มันใช้งานได้และฉันทิ้งมันไว้คนเดียวฮ่า ๆ
Jeff Bluemel

ยอดเยี่ยมมาก! ฉันไม่เคยคิดเลยว่าคุณจะส่งแบบฟอร์มทั้งหมดได้ ขอบคุณ!
ดาราชวา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.