Hace algunos años el cuando quería subir algún archivo a un servidor tenia que, indiscutiblemente, hacer un post a un controlador por medio de un form con el tag enctype (encoding type, por sus siglas en ingles) del tipo multipart/data, La experiencia de usuario era horrible! ya que no sabias que estaba pasando en la subía del archivo o archivos, y para nosotros como desarrolladores era una pesadilla el hacer una experiencia simple y fácil para los usuarios.

No obstante al día de hoy el manejo de archivos del lado del cliente, es decir desde el navegador se ha convertido en una cosa de lo mas trivial gracias al file api de javascript.

Para probarlo voy a demostrar como hacemos para subir un archivo al servidor con javascript puro, sin plugins y una pizca de codigo server-side para manejar los datos.

Para agregarle a la demostración algo de complejidad de la vida real, vamos a crear un formulario html que recibe los datos básicos de un usuario y ademas sube una fotografía, de modo que el post sea verdaderamente “multipart”.

<form id="form" action="javascript: evniar(this)" enctype=" multipart/form-data">
	Nombre:
        <input type="text" name="nombre" />
        DPI (documento personal de identificacion):
        <input type="text" name="dpi" />
        Foto: <br/>
        <input type="file" name="pic" id="pic" />
	<input type="submit" value="Enviar"  />
</form>

El formulario como ven recopila, nombre, numero de identificación y la foto de una persona el código de la función javascript encontes va a crear un preview de la imagen, y al momento de enviar el formulario agregara la imagen, y los campos en la transmisión de datos.

function enviar(form) {
    var persona = new FormData(form);
    var req = ajaxRequest("upload.php");
    req.send(persona);
}

function ajaxRequest(url) {
  if (window.XMLHttpRequest) {
     var request = new XMLHttpRequest();
  } else if(window.ActiveXObject) {
     var request = new ActiveXObject("Microsoft.XMLHTTP");
  }

  request.onload = function(Event) {
     if (request.status == 200) {
       var response = JSON.parse(request.responseText);
       if(response.success){
          alert("Persona procesada exitosamente");
       } else {
          alert("Hubo un problema al procesar, codigo: " + response.status);
       }
     } 
   };

}

En esta parte vemos que hay 2 funciones, una para crear el objeto request ajaxRequest, el cual servirá para transmitir la información al servidor de manera asíncrona y el otro enviar que hace uso de la otra función para enviar el formulario.

El código del servidor que ejecuta la tarea de validar y guardar el archivo en alguna ruta especificada se encontraría en el archivo upload.php de este rompecabezas, y contendría el siguiente código:

<?php
	$foto = $_FILES['pic'];
	$data = array('success' => false);
	
	if(copy($foto['tmp_name'],'ruta/'.$foto['name'])){
		$data = array('success' => true);
	}
	
	echo json_encode($data);
?>

y eso fue todo sobre como subir el archivo, pero que hay de la parte del preview de la imagen?

bien para ello necesitamos mas código de javascript (usando jQuery para algunas partes):

 function leer(input, form) {
        for(var i =0; i< input.files.length; i++){
        if (input.files[i]) {
            var reader = new FileReader();

            reader.onload = function (e) {
               var img = $('<img id="dynamic">');
               img.attr('src', e.target.result);
               img.appendTo(form);
            }
            reader.readAsDataURL(input.files[i]);
           }
        }
    }

que paso aqui? bueno primero iteramos el file input (que puede contener mas de un archivo), luego para cada archivo que leemos declaramos un objeto FileReader del mencionado file api, y en el evento load le agregamos una función que básicamente convierte la imagen en un blob y la agrega al src de un elemento html que se genera dinamicamente y finalmente se le agrega al form en cuestión.

Luego de esto solo es cuestion de agregar unas lineas mas para manejar el evento onchange  del input file, de manera que ejecute el metodo leer  cada vez que se agregue un archivo.

Para esto tenemos 2 opciones:

  1. Agregar el evento onchage en el input file
  2. Crear el codigo javascript para que nuestro html sea mas limpio
//opcion 1
<input type="file" name="pic" id="pic" onchage="javascript:leer()" />

//opcion 2
var archivo = document.getElementById("pic");
archivo.addEventListener("change", function(event) {
  leer();
}

Y así pues, es como podemos subir nuestros ficheros al servidor de una manera fácil rápida y moderna 🙂

Manos al codigo!

Categorized in:

Tagged in:

, ,