martes, 28 de febrero de 2012

Cómo subir archivos con Ajax en HTML5

Cómo subir archivos con Ajax en HTML5: Sí, leíste bien, no es "ajax" disfrazado de Flash o de iFrames, es Ajax. Para lograr esto tenemos que hacer uso de varios poderosos luchadores en forma de APIs que nos ofrece HTML5 (o al menos) los navegadores más actualizados.

Antes que nada me gustaría ofrecer una breve introducción a la tercia ganadora que hará que esto sea posible.

1.- El objeto FormData


Según la MDN el objeto FormData nos permite compilar un conjunto de datos de forma clave/valor para ser enviados vía XHR "Super Saiyajin" o XHR Nivel 2. Estos datos son enviados como cualquier otro, o también usando el método .$ajax({}) de jQuery.

2.- El objeto FileReader


Por medio de este objeto podremos mostrar la imagen subida. La referencia a FileReader también aquí

3.- XHR


Y bueno, sin esto prácticamente no tendría caso el tutorial. Es una de las mejoras en el objeto XHR. Aquí más info sobre él.

Basta de tantas introducciones y veamos cómo se desarrolla la lucha. Es poco código, y se mira feo pero representa bien lo que se quiere mostrar. Sólo necesitamos un archivo con el etiquetado, otro con el javascript y uno para recoger y guardar las imágenes en el servidor; y obvio la carpeta donde se guardarán las imágenes.

El HTML

Código :


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
</head>
<body>
<div class="content">
<input type="file" id="images" name="images[]" />
<button id="btnSubmit">Subir archivo</button>
<ul id="lista-imagenes">

</ul>
<div id="response"></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="/js/upload.js"></script>
</body>
</html>


El javascript.

Código :


(function(){
var input = document.getElementById('images'),
formdata = false;

function mostrarImagenSubida(source){
var list = document.getElementById('lista-imagenes'),
li = document.createElement('li'),
img = document.createElement('img');

img.src = source;
li.appendChild(img);
list.appendChild(li);
}

//Revisamos si el navegador soporta el objeto FormData
if(window.FormData){
formdata = new FormData();
document.getElementById('btnSubmit').style.display = 'none';
}

//Aplicamos la subida de imágenes al evento change del input file
if(input.addEventListener){
input.addEventListener('change', function(evt){
var i = 0, len = this.files.length, img, reader, file;

document.getElementById('response').innerHTML = 'Subiendo...';

//Si hay varias imágenes, las obtenemos una a una
for( ; i < len; i++){
file = this.files[i];

//Una pequeña validación para subir imágenes
if(!!file.type.match(/image.*/)){
//Si el navegador soporta el objeto FileReader
if(window.FileReader){
reader = new FileReader();
//Llamamos a este evento cuando la lectura del archivo es completa
//Después agregamos la imagen en una lista
reader.onloadend = function(e){
mostrarImagenSubida(e.target.result);
};
//Comienza a leer el archivo
//Cuando termina el evento onloadend es llamado
reader.readAsDataURL(file);
}

//Si existe una instancia de FormData
if(formdata)
//Usamos el método append, cuyos parámetros son:
//name : El nombre del campo
//value: El valor del campo (puede ser de tipo Blob, File e incluso string)
formdata.append('images[]', file);
}
}

//Por último hacemos uso del método proporcionado por jQuery para hacer la petición ajax
//Como datos a enviar, el objeto FormData que contiene la información de las imágenes
if(formdata){
$.ajax({
url : 'php/upload.php',
type : 'POST',
data : formdata,
processData : false,
contentType : false,
success : function(res){
document.getElementById('response').innerHTML = res;
}
});
}
}, false);
}
}());


De pasadita el php para recoger y guardar la imagen

Código :


<?php
foreach($_FILES['images']['error'] as $key => $error){
if($error == UPLOAD_ERR_OK){
$name = $_FILES['images']['name'][$key];
move_uploaded_file($_FILES['images']['tmp_name'][$key], 'uploads/' . $name);
}
}

echo "<h2>Archivos correctamente subidos</h2>";
?>


Si quieren subir más de una imagen solo es necesario aplicar el atributo múltiple a la etiqueta input file.
Por último es cuestión de cada desarrollador agregar un "drag&dropeo", progressbar, validaciones o previas de las imágenes.

Recomendado


Me gustaría recomendar un plugin hecho en jQuery que hace todo lo del tutorial y más. Si lo tendría que comparar con un luchador, sería Mil Máscaras sin duda alguna, hace de todo y es muy personalizable además de tener una muy buena documentación, aderezado con el framework bootstrap de Twitter, una joyita.

Espero que les haya gustado mi primer tutorial y para aclarar algunas cosas que creo se han dado en el foro. El Semántico no es una persona, es un personaje y creo debe tomarse como tal, la cuestión es divertirse y tomar gracia de todo.

Gracias :)

Enviar comentario



No hay comentarios:

Publicar un comentario