Cách đăng tệp từ biểu mẫu với Axios


128

Sử dụng HTML thô khi tôi đăng tệp lên máy chủ bình bằng cách sử dụng như sau, tôi có thể truy cập tệp từ yêu cầu bình toàn cầu:

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

Trong bình:

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

Khi tôi cố gắng làm điều tương tự với Axios, toàn cầu yêu cầu bình bị trống:

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

Nếu tôi sử dụng cùng một hàm uploadFile ở trên nhưng xóa tiêu đề json khỏi phương thức axios.post, tôi sẽ nhận được trong khóa biểu mẫu của đối tượng yêu cầu bình của mình một danh sách csv gồm các giá trị chuỗi (tệp là .csv).

Làm cách nào để nhận một đối tượng tệp được gửi qua axios?


@Niklesh vâng, cắt và dán lỗi đánh máy, tôi đã sửa nó ở trên, bao gồm dấu ngoặc kép trong mã.
Don Smythe

bạn đã thử v-on:change="uploadFile"với inputthay vì formthẻ?
Niklesh Raut

@Niklesh Tôi nhận được cùng một kết quả - dữ liệu được gửi dưới dạng chuỗi và được chọn theo request.form chứ không phải request.files trong flask.
Don Smythe

Câu trả lời:


268

Thêm tệp vào một formDatađối tượng và đặt Content-Typetiêu đề thành 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
Sau khi đăng các tập tin. Chúng ta có cần truy cập chúng từ yêu cầu HTTP hay cần truy cập chúng từ các tham số ở phía máy chủ.
Parth Patel

@ParthPatel: Tôi đang sử dụng $_FILESđể có được các file trong phía máy chủ như tôi đang sử dụng PHP
Niklesh Raut

7
Cảm ơn vì bài đăng này, nhưng tôi vẫn không hiểu tại sao chúng tôi cần FormData. Theo doc Axios, cả hai FileFormDatađược coi là chỉ trình duyệt , vì vậy cả hai cách có thể được xem như nhau ( github.com/axios/axios#request-config )
Hiroki

Tuyệt vời ! Tôi đang gửi 'dữ liệu: {data: formData}' đang tạo ra lỗi 412. Nó hoạt động vớidata:formData
Aseem

3
CHÚ Ý: đoạn mã hoạt động như hiện tại khi chạy trong ngữ cảnh của trình duyệt. Để chạy trong node.js, người ta cần chuyển các tiêu đề được tính toán bởi formData.getHeaders()Đây là một vấn đề đã biết với axios; xem ví dụhttps://github.com/axios/axios/issues/789
mjv

13

Ứng dụng mẫu sử dụng Vue. Yêu cầu một máy chủ phụ trợ chạy trên localhost để xử lý yêu cầu:

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


tôi có thể yêu cầu bạn xem một câu hỏi liên quan đến axios ở đây không: stackoverflow.com/questions/59470085/… ?
Istiaque Ahmed

5

Điều này làm việc cho tôi, tôi hy vọng sẽ giúp được ai đó.

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

sử dụng Nuxt - điều này cuối cùng đã làm việc cho tôi. loại bỏ headers: { 'Content-Type': 'multipart/form-data' }là cách duy nhất nó thực sự gửi bài đăng sau khi nhận được phản hồi từ máy chủ từ các tùy chọn. Tôi có thể đang làm gì đó sai, nhưng nó đang hoạt động và tôi đang để nó yên lol
Jeff Bluemel

Điều này là tuyệt vời! Tôi sẽ không bao giờ nghĩ rằng bạn có thể gửi toàn bộ biểu mẫu. Cảm ơn!
Dara Java
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.