Comment utiliser FormData pour le téléchargement de fichiers AJAX?

220

Ceci est mon code HTML que je génère dynamiquement en utilisant la fonctionnalité glisser-déposer.

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

Voici mon code 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
la source
1
Vous devriez lire ceci ( developer.mozilla.org/en-US/docs/Web/API/FormData/append ) la formData();méthode append a un troisième paramètre facultatif pour un fichier.
www139

Réponses:

458

Pour une utilisation correcte des données du formulaire, vous devez effectuer 2 étapes.

Les préparatifs

Vous pouvez donner votre formulaire entier à FormData () pour le traitement

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

ou spécifiez des données exactes pour FormData ()

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

Formulaire d'envoi

La requête Ajax avec jquery ressemblera à ceci:

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

Après cela, il enverra une demande ajax comme vous soumettez un formulaire régulier avec enctype="multipart/form-data"

Mise à jour: Cette demande ne peut pas fonctionner sans type:"POST"options car tous les fichiers doivent être envoyés via une requête POST.

Remarque: contentType: false uniquement disponible à partir de jQuery 1.6

Épeler
la source
1
Puis-je définir le "enctype" dans l'appel Ajax? Je pense que je peux avoir un problème avec cela. Ou, puis-je le définir sur l'objet FormData?
Wouter
Vous pouvez. Pour cela, voir les lignes après CECI DOIT ÊTRE FAIT POUR LE TÉLÉCHARGEMENT DE FICHIER dans mon code.
Épeler le
1
@Spell Comment obtenir des données dans le contrôleur? Avez-vous besoin d'envoyer getCsrfToken?
Юрий Светлов
@ ЮрийСветлов Cela dépend du type de contrôleur que vous utilisez. S'agit-il d'un contrôleur côté serveur ou frontal? Vous essayez de résoudre la protection CSRF ici?
Sort
1
@ManthanJamdagni Lorsque vous obtenez $('form'), il renverra l'objet jQuery. Mais nous avons besoin d'un objet js normal ici sans fonctionnalité jQuery. C'est pourquoi nous obtenons un objet régulier avec [0]notation. Au lieu de cette construction, vous pouvez appeler document.getElementById()ou appeler simultanément.
Sort
37

Je ne peux pas ajouter de commentaire ci-dessus car je n'ai pas assez de réputation, mais la réponse ci-dessus était presque parfaite pour moi, sauf que je devais ajouter

tapez: "POST"

à l'appel .ajax. Je me grattais la tête pendant quelques minutes en essayant de comprendre ce que j'avais fait de mal, c'est tout ce dont il avait besoin et ça me fait plaisir. Voici donc l'extrait entier:

Plein crédit à la réponse ci-dessus, ce n'est qu'un petit ajustement à cela. C'est juste au cas où quelqu'un d'autre serait coincé et ne pourrait pas voir l'évidence.

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

jQuery avec téléchargement de fichier 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();
    }
});

vous pouvez utiliser.

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

ou

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

Les deux fonctionneront.

chandoo
la source
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
la source
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
la source
9
Il est normalement considéré comme une bonne forme de fournir une explication avec une réponse.
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
la source
0

En fait, la documentation montre que vous pouvez utiliser XMLHttpRequest().send() pour envoyer simplement des données multiformes au cas où jquery suce

Richie
la source
0

Mieux vaut utiliser le javascript natif pour trouver l'élément par id comme: 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
la source
-4

Bonjour.

J'ai eu le même problème avec le téléchargement de plusieurs images. La solution était plus simple que je ne l'avais imaginé: inclure [] dans le champ du nom.

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

Je n'ai fait aucune modification sur FormData.

E. Coelho
la source
Cela n'a rien à voir avec le problème sur lequel porte la question et n'est qu'une particularité de la façon dont PHP gère les données de formulaire avec plusieurs valeurs qui portent le même nom.
Quentin