Come utilizzare FormData per il caricamento di file AJAX?


220

Questo è il mio HTML che sto generando dinamicamente usando la funzionalità di trascinamento della selezione.

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

Questo è il mio codice 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
Dovresti leggere questo ( developer.mozilla.org/en-US/docs/Web/API/FormData/append ) il formData();metodo append ha un terzo parametro opzionale per un file.
www139,

Risposte:


459

Per un corretto utilizzo dei dati del modulo è necessario eseguire 2 passaggi.

preparativi

È possibile fornire l'intero modulo a FormData () per l'elaborazione

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

o specifica i dati esatti per FormData ()

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

Modulo di invio

La richiesta Ajax con jquery sarà simile a questa:

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

Dopodiché invierà una richiesta Ajax come si invia il modulo regolare con enctype="multipart/form-data"

Aggiornamento: questa richiesta non può funzionare senza type:"POST"opzioni poiché tutti i file devono essere inviati tramite richiesta POST.

Nota: contentType: false disponibile solo da jQuery 1.6 in poi


1
Posso impostare l '"enctype" nella chiamata Ajax? Penso che potrei avere un problema con esso. Oppure, posso impostarlo sull'oggetto FormData?
Wouter,

Puoi. Per questo vedi le righe dopo QUESTA DEVE ESSERE EFFETTUATA PER IL CARICAMENTO DEI FILE nel mio codice.
Incantesimo

1
@Spell Come ottenere i dati nel controller? Hai bisogno di inviare getCsrfToken?
Юрий Светлов,

@ ЮрийСветлов Questo dipende dal tipo di controller che usi. È il controller lato server o lato anteriore? Stai cercando di risolvere la protezione CSRF qui?
Incantesimo

1
@ManthanJamdagni Quando otterrai $('form'), restituirà l'oggetto jQuery. Ma qui abbiamo bisogno dell'oggetto js regolare senza la funzionalità jQuery. Ecco perché otteniamo oggetti regolari con [0]notazione. Invece di questa costruzione è possibile chiamare document.getElementById()o chiamata simulare.
Incantesimo

37

Non posso aggiungere un commento sopra perché non ho abbastanza reputazione, ma la risposta sopra era quasi perfetta per me, tranne che dovevo aggiungere

tipo: "POST"

alla chiamata .ajax. Mi sono grattato la testa per qualche minuto cercando di capire cosa avevo fatto di sbagliato, è tutto ciò di cui avevo bisogno e funziona a meraviglia. Quindi questo è l'intero frammento:

Pieno merito alla risposta sopra di me, questo è solo un piccolo accorgimento. Questo è solo nel caso in cui qualcun altro si blocchi e non riesca a vedere l'ovvio.

  $.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 con caricamento del 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();
    }
});

Puoi usare.

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

o

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

Entrambi funzioneranno.


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
Normalmente è considerata una buona forma per fornire una spiegazione insieme a una risposta.
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

In realtà la documentazione mostra che è possibile utilizzare XMLHttpRequest().send() semplicemente per inviare dati multiformi in caso di jquery


0

Meglio usare il javascript nativo per trovare l'elemento per id come: 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

Buongiorno.

Ho avuto lo stesso problema con il caricamento di più immagini. La soluzione era più semplice di quanto avessi immaginato: includi [] nel campo del nome.

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

Non ho apportato alcuna modifica a FormData.


Ciò non ha nulla a che fare con il problema che pone la domanda ed è solo una peculiarità di come PHP gestisce i dati dei moduli con più valori con lo stesso nome.
Quentin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.