> Manuales > Taller de jQuery

Script Javascript para realizar un upload de archivos al servidor por Ajax, usando el objeto nativo FormData y con la ayuda de jQuery.

Si nos hubieras preguntado hace años habríamos dicho que era imposible enviar archivos al servidor por Ajax, para hacer un upload sin necesidad de recargar la página. Sin embargo Javascript actualmente sí permite esta posibilidad.

En este artículo vamos a explicar un script Javascript que nos serviría para realizar una conexión por Ajax con un servidor en la que mandemos datos de formulario junto con ficheros de datos. Esa conexión la realizaremos por Ajax, de modo que no se tenga que recargar la página o recurrir a viejos trucos como un iframe.

Para hacer posible este objetivo existe un objeto nativo Javascript llamado FormData que nos permitirá crear la estructura necesaria para enviar datos por post, por medio de programación. Por decirlo de otra manera, con FormData conseguiremos generar lo mismo que hace el navegador automáticamente cuando se realiza el envío de un formulario. Solo que en este caso será mediante Javascript y donde podremos inyectar cualquier dato, incluso aunque no esté presente en un formulario.

Éste sería el único método nativo en Javascript para realizar envío de archivos, para hacer upload a un servidor, por medio de Ajax. Nosotros usamos jQuery para facilitarnos la tarea, pero hay que aclarar especialmente que no es necesario para nada. Es decir, usamos jQuery porque así es más fácil hacer Ajax, siendo más sencillo para los que estamos acostumbrados a esta librería Javascript.

FormData

Merecería la pena tratar aparte FormData, aunque de momento vamos a ofrecer solamente la información necesaria para entender este ejemplo. Es un objeto (quizás se entiende mejor como una clase, aunque sabemos que no existen las clases como tal en Javascript) que nos permite a su vez crear objetos FormData para generar pares clave/valor que luego pueden ser enviados del mismo modo que los formularios. También serán recogidos en el servidor del mismo modo que se reciben los formularios.

Cuando generas un objeto FormData la información que vas agregando con append() usa el formato de los formularios comunes que tienen el atributo "multipart/form-data".

Nota: FormData está presente en todos los navegadores modernos, aunque en el caso de Internet Explorer sólo lo encontraremos a partir de la versión 10.

Cuando tenemos un objeto FormData disponemos en él de un método append() que nos permite agregar ese par llave/valor. Los datos que podemos agregar pueden provenir de formularios que ya tengamos creados, pero también de cualquier otra fuente, recurso o servicio que dispongamos en Javascript. Este método append() recibe varios parámetros, de momento indicaremos como primer parámetro el nombre del dato y como segundo el valor.

var formData = new FormData();
formData.append("clave", "valor");

Mi formulario con campos INPUT FILE

Esta parte es puramente HTML. El formulario lo crearás igual que creas cualquier otro formulario común. Tendrás uno o varios campos FILE que serán los que enviemos por Ajax junto con otros campos que pueda haber.

<form enctype="multipart/form-data" id="formuploadajax" method="post">
        Nombre: <input type="text" name="nombre" placeholder="Escribe tu nombre">
        <br />
        <input  type="file" id="archivo1" name="archivo1"/>
        <br />
        <input  type="file" id="archivo2" name="archivo2"/>
        <br />
        <input type="submit" value="Subir archivos"/>
    </form>
    <div id="mensaje"></div>

Observarás que además del formulario hemos colocado una división con id="mensaje". Luego sobre ese elemento enviaremos el texto de la respuesta de la conexión Ajax. El resto del código es HTML común, donde puedes fijarte que tenemos un campo INPUT TEXT y dos campos INPUT para FILE.

Mi Javascript para realizar el envío de archivos por Ajax

Veremos que realizar un ejemplo de envío por Ajax de archivos es realmente simple, incluso con la propia llamada a Ajax. Lo haremos en pocas líneas de código. No obstante, para aclararnos mejor, explicaremos el código en diversos pasos.

Nota: Queremos justamente mantenerlo sencillo, por eso vamos a resumir los pasos a los mínimos necesarios. Lógicamente con tu Javascript podrás hacer más cosas. Existen scripts en Internet para realizar comportamientos similares pero más complejos, incorporando elementos accesorios como barras de progreso.

Este sería el guión que vamos a tener que implementar:

1) Crear un evento submit para enviar el formulario con jQuery en lugar de dejar que lo envíe por el método predeterminado el navegador.

Este comportamiento es puramente jQuery y si no lo conoces simplemente decirte que está explicado en el Manual de jQuery. Lo consigues con un código como éste.

$("#formuploadajax").on("submit", function(e){
    e.preventDefault();
    var f = $(this);

    // ... resto del código de mi ejercicio
});

2) Generar el objeto FormData a partir del formulario y agregarle los datos del formulario. Además podremos agregar cualquier otro dato, incluso aunque éste no esté en un campo del formulario.

var formData = new FormData(document.getElementById("formuploadajax"));
formData.append("dato", "valor");

Observarás que al hacer el new FormData() enviamos como parámetro el propio formulario, con el objeto formulario nativo de Javascript. Ésto es para que el propio juego de datos se genere a partir de los campos que hay en el HTML del formulario. Con este paso nos ahorramos tener que hacer los append() de cada archivo que queremos subir.

En la segunda línea tenemos una llamada a append() que es innecesaria para cubrir nuestros objetivos, pero que he colocado para que se vea simplemente cómo agregaríamos con ese método cualquier otro dato que podamos necesitar.

3) La llamada a Ajax, que realizamos con el método $.ajax() de jQuery.

Vemos que se deben establecer varias variables de configuración para la conexión Ajax. La que debe llamarte la atención es "data:", que es el juego de datos que queremos enviar por post al servidor. Fíjate que como juego de datos usamos directamente el objeto formData generado anteriormente.

$.ajax({
    url: "recibe.php",
    type: "post",
    dataType: "html",
    data: formData,
    cache: false,
    contentType: false,
    processData: false
})
    .done(function(res){
        $("#mensaje").html("Respuesta: " + res);
    });

También podrás ver como se define un método done() sobre la misma conexión Ajax, para especificar las acciones Javascript a implementar cuando se reciba la respuesta por parte del servidor.

Con eso es todo! no necesitas hacer nada más, al menos por lo que a Javascript respecta, para realizar ese envío de ficheros de manera asíncrona. Ahora te querdaría la parte de gestionar el upload de los archivos del lado del servidor. Eso ya depende del lenguaje de servidor que estés usando. Aquí en DesarrolloWeb.com te lo explicamos en otros artículos para diferentes lenguajes.

Código completo

Para que sea más fácil de ver y por si hay alguna duda, colocamos el código completo de una página que realizaría el upload con Ajax, tal como lo hemos explicado.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload de archivos con Ajax</title>
</head>
<body>
    
    <form enctype="multipart/form-data" id="formuploadajax" method="post">
        Nombre: <input type="text" name="nombre" placeholder="Escribe tu nombre">
        <br />
        <input  type="file" id="archivo1" name="archivo1"/>
        <br />
        <input  type="file" id="archivo2" name="archivo2"/>
        <br />
        <input type="submit" value="Subir archivos"/>
    </form>
    <div id="mensaje"></div>
    
    
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script>
    $(function(){
        $("#formuploadajax").on("submit", function(e){
            e.preventDefault();
            var f = $(this);
            var formData = new FormData(document.getElementById("formuploadajax"));
            formData.append("dato", "valor");
            //formData.append(f.attr("name"), $(this)[0].files[0]);
            $.ajax({
                url: "recibe.php",
                type: "post",
                dataType: "html",
                data: formData,
                cache: false,
                contentType: false,
	     processData: false
            })
                .done(function(res){
                    $("#mensaje").html("Respuesta: " + res);
                });
        });
    });
    </script>
</body>
</html>

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual