Wie verwende ich FormData für das Hochladen von AJAX-Dateien?

220

Dies ist mein HTML-Code, den ich dynamisch mithilfe der Drag & Drop-Funktion generiere.

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

Dies ist mein JavaScript-Code:

<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
quelle
1
Sie sollten dies lesen ( developer.mozilla.org/en-US/docs/Web/API/FormData/append ). Die formData();Append-Methode verfügt über einen optionalen dritten Parameter für eine Datei.
www139

Antworten:

458

Für eine korrekte Verwendung der Formulardaten müssen Sie zwei Schritte ausführen.

Vorbereitungen

Sie können FormData () Ihr gesamtes Formular zur Verarbeitung übergeben

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

oder genaue Daten für FormData () angeben

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

Formular senden

Eine Ajax-Anfrage mit jquery sieht folgendermaßen aus:

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

Danach wird eine Ajax-Anfrage gesendet, wie Sie das reguläre Formular mit senden enctype="multipart/form-data"

Update: Diese Anforderung kann nicht ohne type:"POST"Optionen funktionieren , da alle Dateien per POST-Anforderung gesendet werden müssen.

Hinweis: contentType: false Nur ab jQuery 1.6 verfügbar

Buchstabieren
quelle
1
Kann ich den "Enctype" im Ajax-Aufruf festlegen? Ich denke, ich könnte ein Problem damit haben. Oder kann ich es für das FormData-Objekt festlegen?
Wouter
Sie können. Siehe hierzu die Zeilen danach, die zum Hochladen der Datei in meinem Code ausgeführt werden müssen.
Zauber
1
@Spell Wie bekomme ich Daten in Controller? Müssen Sie senden getCsrfToken?
22рий Светлов
@ ЮрийСветлов Dies hängt davon ab, welche Art von Controller Sie verwenden. Ist es Server- oder Front-Side-Controller? Versuchen Sie hier, den CSRF-Schutz zu lösen?
Zauber
1
@ManthanJamdagni Wenn Sie erhalten $('form'), wird das jQuery-Objekt zurückgegeben. Wir benötigen hier jedoch ein reguläres js-Objekt ohne jQuery-Funktionalität. Deshalb erhalten wir reguläre Objekte mit [0]Notation. Anstelle dieser Konstruktion können Sie auch anrufen document.getElementById()oder simulieren.
Zauber
37

Ich kann oben keinen Kommentar hinzufügen, da ich nicht genug Ruf habe, aber die obige Antwort war fast perfekt für mich, außer ich musste hinzufügen

Typ: "POST"

zum .ajax Anruf. Ich kratzte mir ein paar Minuten am Kopf, um herauszufinden, was ich falsch gemacht hatte. Das ist alles, was ich brauchte, und es ist ein Vergnügen. Das ist also der ganze Ausschnitt:

Volle Anerkennung für die Antwort über mir, dies ist nur eine kleine Änderung. Dies ist nur für den Fall, dass jemand anderes stecken bleibt und das Offensichtliche nicht sehen kann.

  $.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
quelle
20
<form id="upload_form" enctype="multipart/form-data">

jQuery mit CodeIgniter-Datei hochladen:

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();
    }
});

Sie können verwenden.

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

oder

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

Beides wird funktionieren.

Chandoo
quelle
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
quelle
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
quelle
9
Es wird normalerweise als gute Form angesehen, eine Erklärung zusammen mit einer Antwort zu liefern.
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
quelle
0

Tatsächlich zeigt die Dokumentation, dass Sie XMLHttpRequest().send() einfach multiforme Daten senden können, falls jquery nicht funktioniert

Richie
quelle
0

Verwenden Sie besser das native Javascript, um das Element anhand der folgenden ID zu finden: 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
quelle
-4

Guten Morgen.

Ich hatte das gleiche Problem beim Hochladen mehrerer Bilder. Die Lösung war einfacher als ich es mir vorgestellt hatte: Fügen Sie [] in das Namensfeld ein.

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

Ich habe keine Änderungen an FormData vorgenommen.

E. Coelho
quelle
Dies hat nichts mit dem Problem zu tun, nach dem sich die Frage stellt, und ist nur eine Besonderheit dessen, wie PHP Formulardaten mit mehreren Werten mit demselben Namen behandelt.
Quentin