¿Subir datos y archivos en un solo formulario usando Ajax?

Resuelto Dan asked hace 12 años • 13 respuestas

Estoy usando jQuery y Ajax en mis formularios para enviar datos y archivos, pero no estoy seguro de cómo enviar datos y archivos en un solo formulario.

Actualmente hago casi lo mismo con ambos métodos pero la forma en la que se reúnen los datos en una matriz es diferente, los datos usan .serialize();pero los archivos usan= new FormData($(this)[0]);

¿Es posible combinar ambos métodos para poder subir archivos y datos de un solo formulario a través de Ajax?

Datos jQuery, Ajax y html

$("form#data").submit(function(){

    var formData = $(this).serialize();

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="data" method="post">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <button>Submit</button>
</form>

Archivos jQuery, Ajax y html

$("form#files").submit(function(){

    var formData = new FormData($(this)[0]);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="files" method="post" enctype="multipart/form-data">
    <input name="image" type="file" />
    <button>Submit</button>
</form>

¿Cómo puedo combinar lo anterior para poder enviar datos y archivos en un solo formulario a través de Ajax?

Mi objetivo es poder enviar todo este formulario en una sola publicación con Ajax, ¿es posible?

<form id="datafiles" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>
Dan avatar Jun 05 '12 21:06 Dan
Aceptado

El problema que tuve fue usar el identificador jQuery incorrecto.

Puede cargar datos y archivos con un formulario usando ajax .

PHP+HTML

<?php

print_r($_POST);
print_r($_FILES);
?>

<form id="data" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>

jQuery+Ajax

$("form#data").submit(function(e) {
    e.preventDefault();    
    var formData = new FormData(this);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });
});

Version corta

$("form#data").submit(function(e) {
    e.preventDefault();
    var formData = new FormData(this);    

    $.post($(this).attr("action"), formData, function(data) {
        alert(data);
    });
});
Dan avatar Jun 05 '2012 15:06 Dan

Otra opción es utilizar un iframe y establecerle el destino del formulario.

puedes probar esto (usa jQuery):

function ajax_form($form, on_complete)
{
    var iframe;

    if (!$form.attr('target'))
    {
        //create a unique iframe for the form
        iframe = $("<iframe></iframe>").attr('name', 'ajax_form_' + Math.floor(Math.random() * 999999)).hide().appendTo($('body'));
        $form.attr('target', iframe.attr('name'));
    }

    if (on_complete)
    {
        iframe = iframe || $('iframe[name="' + $form.attr('target') + '"]');
        iframe.load(function ()
        {
            //get the server response
            var response = iframe.contents().find('body').text();
            on_complete(response);
        });
    }
}

Funciona bien con todos los navegadores, no es necesario serializar ni preparar los datos. Una desventaja es que no se puede monitorear el progreso.

Además, al menos para Chrome, la solicitud no aparecerá en la pestaña "xhr" de las herramientas de desarrollo sino en "doc".

Roey avatar May 02 '2016 07:05 Roey