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

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


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

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.


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

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

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



}); 

0

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


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

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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.