Jak korzystać z FormData do przesyłania plików AJAX?

220

To jest mój HTML, który generuję dynamicznie za pomocą funkcji przeciągnij i upuść.

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

To jest mój kod JavaScript:

<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
źródło
1
Powinieneś przeczytać to ( developer.mozilla.org/en-US/docs/Web/API/FormData/append ) formData();metoda dołączania ma opcjonalny trzeci parametr dla pliku.
www139,

Odpowiedzi:

458

Aby poprawnie korzystać z danych formularza, musisz wykonać 2 kroki.

Przygotowania

Możesz przekazać cały formularz FormData () do przetworzenia

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

lub podaj dokładne dane dla FormData ()

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

Formularz wysyłania

Żądanie Ajax z jquery wygląda następująco:

$.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
});

Następnie wyśle ​​prośbę o ajax, tak jak przedkładasz zwykły formularz za pomocą enctype="multipart/form-data"

Aktualizacja: To żądanie nie może działać bez type:"POST"opcji, ponieważ wszystkie pliki muszą zostać wysłane za pomocą żądania POST.

Uwaga: contentType: false dostępne tylko od wersji jQuery 1.6

Zaklęcie
źródło
1
Czy mogę ustawić „typ” w wywołaniu Ajax? Myślę, że mogę mieć z tym problem. Czy mogę ustawić go na obiekcie FormData?
Wouter
Możesz. W tym celu zobacz wiersze po TO MUSZĄ ZROBIĆ DO PRZESYŁANIA PLIKÓW w moim kodzie.
Zaklęcie
1
@Spell Jak uzyskać dane w kontrolerze? Potrzebujesz wysłać getCsrfToken?
Юрий Светлов
@ ЮрийСветлов To zależy od rodzaju używanego kontrolera. Czy to kontroler po stronie serwera, czy po stronie serwera? Próbujesz tutaj rozwiązać ochronę CSRF?
Zaklęcie
1
@ManthanJamdagni Gdy otrzymasz $('form'), zwróci obiekt jQuery. Ale potrzebujemy tutaj zwykłego obiektu js bez funkcji jQuery. Dlatego otrzymujemy zwykły obiekt z [0]notacją. Zamiast tej konstrukcji możesz zadzwonić document.getElementById()lub połączyć się równolegle.
Zaklęcie
37

Nie mogę dodać komentarza powyżej, ponieważ nie mam wystarczającej reputacji, ale powyższa odpowiedź była dla mnie prawie idealna, tyle że musiałem dodać

wpisz: „POST”

do połączenia .ajax. Drapałem się po głowie przez kilka minut, próbując dowiedzieć się, co zrobiłem źle, to wszystko, czego potrzeba i działa na ucztę. Oto cały fragment:

Pełne podziękowania dla odpowiedzi nade mną, to tylko drobna poprawka do tego. Dzieje się tak na wypadek, gdyby ktoś utknął i nie widział oczywistości.

  $.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
źródło
20
<form id="upload_form" enctype="multipart/form-data">

jQuery z przesyłaniem pliku 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();
    }
});

możesz użyć.

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

lub

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

Oba będą działać.

chandoo
źródło
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
źródło
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
źródło
9
Zwykle uważa się, że należy podać wyjaśnienie wraz z odpowiedzią.
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
źródło
0

W rzeczywistości dokumentacja pokazuje, że możesz użyć XMLHttpRequest().send() do wysłania danych wielopostaciowych na wypadek, gdyby jquery było do bani

Richie
źródło
0

Lepiej użyć natywnego javascript do znalezienia elementu według identyfikatora, na przykład: 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');
    });
Ranch Camal
źródło
-4

Dzień dobry.

Miałem ten sam problem z przesyłaniem wielu zdjęć. Rozwiązanie było prostsze niż się spodziewałem: w polu nazwy wpisz [].

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

Nie wprowadziłem żadnych zmian w FormData.

E. Coelho
źródło
Nie ma to nic wspólnego z problemem, o który zadaje pytanie, i jest tylko osobliwością tego, jak PHP obsługuje dane z wieloma wartościami o tej samej nazwie.
Quentin