Bagaimana cara menggunakan FormData untuk mengunggah file AJAX?

220

Ini adalah HTML saya yang saya hasilkan secara dinamis menggunakan fungsionalitas drag and drop.

<form method="POST" id="contact" name="13" class="form-horizontal wpc_contact" novalidate="novalidate" enctype="multipart/form-data">
<fieldset>
    <div id="legend" class="">
        <legend class="">file demoe 1</legend>
        <div id="alert-message" class="alert hidden"></div>
    </div>

    <div class="control-group">
        <!-- Text input-->
        <label class="control-label" for="input01">Text input</label>
        <div class="controls">
            <input type="text" placeholder="placeholder" class="input-xlarge" name="name">
            <p class="help-block" style="display:none;">text_input</p>
        </div>
        <div class="control-group">  </div>
        <label class="control-label">File Button</label>

        <!-- File Upload --> 
        <div class="controls">
            <input class="input-file" id="fileInput" type="file" name="file">
        </div>
    </div>
    <div class="control-group">    

        <!-- Button --> 
        <div class="controls">
            <button class="btn btn-success">Button</button>
        </div>
    </div>
</fieldset>
</form> 

Ini adalah kode JavaScript saya:

<script>
    $('.wpc_contact').submit(function(event){
        var formname = $('.wpc_contact').attr('name');
        var form = $('.wpc_contact').serialize();               
        var FormData = new FormData($(form)[1]);

        $.ajax({
            url : '<?php echo plugins_url(); ?>'+'/wpc-contact-form/resources/js/tinymce.php',
            data : {form:form,formname:formname,ipadd:ipadd,FormData:FormData},
            type : 'POST',
            processData: false,
            contentType: false,
            success : function(data){
            alert(data); 
            }
        });
   }
Kalpit
sumber
1
Anda harus membaca ini ( developer.mozilla.org/en-US/docs/Web/API/FormData/append ) formData();metode append memiliki parameter ketiga opsional untuk file.
www139

Jawaban:

458

Untuk penggunaan data formulir yang benar, Anda perlu melakukan 2 langkah.

Persiapan

Anda bisa memberikan seluruh formulir Anda ke FormData () untuk diproses

var form = $('form')[0]; // You need to use standard javascript object here
var formData = new FormData(form);

atau tentukan data pasti untuk FormData ()

var formData = new FormData();
formData.append('section', 'general');
formData.append('action', 'previewImg');
// Attach file
formData.append('image', $('input[type=file]')[0].files[0]); 

Mengirim formulir

Permintaan Ajax dengan jquery akan terlihat seperti ini:

$.ajax({
    url: 'Your url here',
    data: formData,
    type: 'POST',
    contentType: false, // NEEDED, DON'T OMIT THIS (requires jQuery 1.6+)
    processData: false, // NEEDED, DON'T OMIT THIS
    // ... Other options like success and etc
});

Setelah ini, ia akan mengirim permintaan ajax seperti Anda mengirimkan formulir biasa dengan enctype="multipart/form-data"

Pembaruan: Permintaan ini tidak dapat berfungsi tanpa type:"POST"opsi karena semua file harus dikirim melalui permintaan POST.

Catatan: contentType: false hanya tersedia dari jQuery 1.6 dan seterusnya

Mengeja
sumber
1
Bisakah saya mengatur "enctype" di panggilan Ajax? Saya pikir saya mungkin memiliki masalah dengan itu. Atau, dapatkah saya mengaturnya di objek FormData?
Wouter
Kamu bisa. Untuk ini, lihat baris setelah INI HARUS DILAKUKAN UNTUK MENGUNGKAPKAN FILE dalam kode saya.
Eja
1
@Spell Bagaimana mendapatkan data di controller? Perlu kirim getCsrfToken?
Юрий Светлов
@ ЮрийСветлов Ini tergantung pada jenis pengontrol yang Anda gunakan. Apakah itu server side atau front side controller? Anda mencoba menyelesaikan perlindungan CSRF di sini?
Eja
1
@ManthanJamdagni Ketika Anda mendapatkan $('form'), itu akan mengembalikan objek jQuery. Tapi kita perlu objek js reguler di sini tanpa fungsionalitas jQuery. Itu sebabnya kita mendapatkan objek reguler dengan [0]notasi. Alih-alih konstruksi ini Anda dapat memanggil document.getElementById()atau panggilan simular.
Eja
37

Saya tidak dapat menambahkan komentar di atas karena saya tidak memiliki reputasi yang cukup, tetapi jawaban di atas hampir sempurna untuk saya, kecuali saya harus menambahkan

ketik: "POST"

ke panggilan .ajax. Aku menggaruk-garuk kepalaku selama beberapa menit, mencoba mencari tahu apa yang telah kulakukan salah, hanya itu yang diperlukan dan berhasil mengobati. Jadi ini keseluruhan cuplikan:

Penghargaan penuh untuk jawaban di atas saya, ini hanya sedikit perubahan untuk itu. Ini hanya untuk berjaga-jaga jika ada orang lain yang macet dan tidak bisa melihat yang jelas.

  $.ajax({
    url: 'Your url here',
    data: formData,
    type: "POST", //ADDED THIS LINE
    // THIS MUST BE DONE FOR FILE UPLOADING
    contentType: false,
    processData: false,
    // ... Other options like success and etc
})
supertemp
sumber
20
<form id="upload_form" enctype="multipart/form-data">

jQuery dengan unggahan file CodeIgniter:

var formData = new FormData($('#upload_form')[0]);

formData.append('tax_file', $('input[type=file]')[0].files[0]);

$.ajax({
    type: "POST",
    url: base_url + "member/upload/",
    data: formData,
    //use contentType, processData for sure.
    contentType: false,
    processData: false,
    beforeSend: function() {
        $('.modal .ajax_data').prepend('<img src="' +
            base_url +
            '"asset/images/ajax-loader.gif" />');
        //$(".modal .ajax_data").html("<pre>Hold on...</pre>");
        $(".modal").modal("show");
    },
    success: function(msg) {
        $(".modal .ajax_data").html("<pre>" + msg +
            "</pre>");
        $('#close').hide();
    },
    error: function() {
        $(".modal .ajax_data").html(
            "<pre>Sorry! Couldn't process your request.</pre>"
        ); // 
        $('#done').hide();
    }
});

kamu bisa memakai.

var form = $('form')[0]; 
var formData = new FormData(form);     
formData.append('tax_file', $('input[type=file]')[0].files[0]);

atau

var formData = new FormData($('#upload_form')[0]);
formData.append('tax_file', $('input[type=file]')[0].files[0]); 

Keduanya akan bekerja.

Chandoo
sumber
1
$(document).ready(function () {
    $(".submit_btn").click(function (event) {
        event.preventDefault();
        var form = $('#fileUploadForm')[0];
        var data = new FormData(form);
        data.append("CustomField", "This is some extra data, testing");
        $("#btnSubmit").prop("disabled", true);
        $.ajax({
            type: "POST",
            enctype: 'multipart/form-data',
            url: "upload.php",
            data: data,
            processData: false,
            contentType: false,
            cache: false,
            timeout: 600000,
            success: function (data) {
                console.log();
            },
        });
    });
});
Ankush Kumar
sumber
0
View:
<label class="btn btn-info btn-file">
Import <input type="file" style="display: none;">
</label>
<Script>
$(document).ready(function () {
                $(document).on('change', ':file', function () {
                    var fileUpload = $(this).get(0);
                    var files = fileUpload.files;
                    var bid = 0;
                    if (files.length != 0) {
                        var data = new FormData();
                        for (var i = 0; i < files.length ; i++) {
                            data.append(files[i].name, files[i]);
                        }
                        $.ajax({
                            xhr: function () {
                                var xhr = $.ajaxSettings.xhr();
                                xhr.upload.onprogress = function (e) {
                                    console.log(Math.floor(e.loaded / e.total * 100) + '%');
                                };
                                return xhr;
                            },
                            contentType: false,
                            processData: false,
                            type: 'POST',
                            data: data,
                            url: '/ControllerX/' + bid,
                            success: function (response) {
                                location.href = 'xxx/Index/';
                            }
                        });
                    }
                });
            });
</Script>
Controller:
[HttpPost]
        public ActionResult ControllerX(string id)
        {
            var files = Request.Form.Files;
...
Vkl125
sumber
9
Biasanya dianggap sebagai bentuk yang baik untuk memberikan penjelasan beserta jawaban.
ouflak
0
$('#form-withdraw').submit(function(event) {

    //prevent the form from submitting by default
    event.preventDefault();



    var formData = new FormData($(this)[0]);

    $.ajax({
        url: 'function/ajax/topup.php',
        type: 'POST',
        data: formData,
        async: false,
        cache: false,
        contentType: false,
        processData: false,
        success: function (returndata) {
          if(returndata == 'success')
          {
            swal({
              title: "Great",
              text: "Your Form has Been Transfer, We will comfirm the amount you reload in 3 hours",
              type: "success",
              showCancelButton: false,
              confirmButtonColor: "#DD6B55",
              confirmButtonText: "OK",
              closeOnConfirm: false
            },
            function(){
              window.location.href = '/transaction.php';
            });
          }

          else if(returndata == 'Offline')
          {
              sweetAlert("Offline", "Please use other payment method", "error");
          }
        }
    });



}); 
Shaiful Ezani
sumber
0

Sebenarnya Dokumentasi menunjukkan bahwa Anda dapat menggunakan XMLHttpRequest().send() hanya mengirim data multiformis dalam kasus jquery menyebalkan

Richie
sumber
0

Lebih baik menggunakan javascript asli untuk menemukan elemen dengan id seperti: document.getElementById ("yourFormElementID") .

$.ajax( {
      url: "http://yourlocationtopost/",
      type: 'POST',
      data: new FormData(document.getElementById("yourFormElementID")),
      processData: false,
      contentType: false
    } ).done(function(d) {
           console.log('done');
    });
Peternakan Camal
sumber
-4

Selamat pagi.

Saya memiliki masalah yang sama dengan mengunggah banyak gambar. Solusi lebih sederhana daripada yang saya bayangkan: sertakan [] di bidang nama.

<input type="file" name="files[]" multiple>

Saya tidak melakukan modifikasi apa pun pada FormData.

E. Coelho
sumber
Ini tidak ada hubungannya dengan masalah pertanyaan yang ditanyakan dan hanya kekhasan bagaimana PHP menangani data formulir dengan beberapa nilai yang memiliki nama yang sama.
Quentin