¿Cómo usar FormData para cargar archivos AJAX?

220

Este es mi HTML que estoy generando dinámicamente usando la funcionalidad de arrastrar y soltar.

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

Este es mi código 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
fuente
1
Debe leer esto ( developer.mozilla.org/en-US/docs/Web/API/FormData/append ), el formData();método append tiene un tercer parámetro opcional para un archivo.
www139

Respuestas:

458

Para el uso correcto de los datos del formulario, debe realizar 2 pasos.

Preparativos

Puede entregar su formulario completo a FormData () para su procesamiento

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

o especifique datos exactos para FormData ()

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

Enviando formulario

La solicitud de Ajax con jquery se verá así:

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

Después de esto, enviará una solicitud ajax como si enviaras un formulario regular con enctype="multipart/form-data"

Actualización: esta solicitud no puede funcionar sin type:"POST"opciones, ya que todos los archivos deben enviarse a través de la solicitud POST.

Nota: contentType: false solo disponible desde jQuery 1.6 en adelante

Deletrear
fuente
1
¿Puedo configurar el "enctype" en la llamada Ajax? Creo que puedo tener un problema con eso. ¿O puedo configurarlo en el objeto FormData?
Wouter
Usted puede. Para esto, vea líneas después de ESTO DEBE HACERSE PARA CARGAR ARCHIVOS en mi código.
Deletrear el
1
@Spell ¿Cómo obtener datos en el controlador? ¿Necesito enviar getCsrfToken?
Срий Светлов
@ ЮрийСветлов Esto depende del tipo de controlador que utilice. ¿Es el lado del servidor o el controlador del lado frontal? ¿Intentas resolver la protección CSRF aquí?
Deletrear el
1
@ManthanJamdagni Cuando llegue $('form'), devolverá el objeto jQuery. Pero necesitamos un objeto js regular aquí sin la funcionalidad jQuery. Es por eso que obtenemos objetos regulares con [0]notación. En lugar de esta construcción puede llamar document.getElementById()o llamar simular.
Hechizo el
37

No puedo agregar un comentario arriba porque no tengo suficiente reputación, pero la respuesta anterior fue casi perfecta para mí, excepto que tuve que agregar

tipo: "POST"

a la llamada .ajax. Estuve rascándome la cabeza por unos minutos tratando de descubrir qué había hecho mal, eso es todo lo que necesitaba y funciona de maravilla. Entonces este es todo el fragmento:

Crédito completo a la respuesta por encima de mí, esto es solo un pequeño ajuste a eso. Esto es solo en caso de que alguien más se quede atascado y no pueda ver lo obvio.

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

jQuery con carga de archivo 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();
    }
});

puedes usar.

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

Ambos funcionarán.

chandoo
fuente
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
fuente
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
fuente
99
Normalmente se considera buena forma proporcionar una explicación junto con una respuesta.
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
fuente
0

En realidad, la documentación muestra que puede usar XMLHttpRequest().send() simplemente enviar datos multiformes en caso de que jquery sea una mierda

Richie
fuente
0

Es mejor usar el javascript nativo para encontrar el elemento por id como: 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');
    });
Rancho Camal
fuente
-4

Buenos días.

Tuve el mismo problema con la carga de varias imágenes. La solución fue más simple de lo que había imaginado: incluir [] en el campo de nombre.

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

No hice ninguna modificación en FormData.

E. Coelho
fuente
Esto no tiene nada que ver con el problema que plantea la pregunta y es solo una peculiaridad de cómo PHP maneja los datos de formulario con múltiples valores que tienen el mismo nombre.
Quentin