Subiendo archivos con AJAX

Parece que no puedo llegar al final de lo divertido que puedes hacer con las tecnologías web emergentes. Hoy, les mostraré cómo hacer algo que, hasta el último momento, ha sido casi sin precedentes: cargar archivos a través de AJAX..

Oh, claro, ha habido hacks; Pero si eres como yo, y te sientes sucio cada vez que escribes iframe, Te va a gustar mucho esto. Únete a mí después del salto!

Buscando una solución rápida?

Si está buscando una solución rápida, hay una gran colección de scripts y aplicaciones de carga de archivos en Envato Market.

Este cargador de archivos HTML5 es particularmente ingenioso: puedes agregar archivos fácilmente arrastrándolos y soltándolos o haciendo clic. Todos los archivos se cargarán a través de AJAX o se pueden agregar dentro de un formulario, y los archivos se pueden renombrar antes de cargarlos. Una gran solución rápida si eso es lo que estás buscando.!


¿Por qué no terminamos con las malas noticias??

Esto no funciona en todos los navegadores. Sin embargo, con algunas mejoras progresivas (o cualquiera que sea la palabra de moda actual), tendremos una página de carga que funcionará de nuevo en IE6 (aunque sin los bits AJAXy).

Nuestra carga AJAX funcionará mientras FormData está disponible; De lo contrario, el usuario obtendrá una carga normal..

Hay tres componentes principales de nuestro proyecto..

  • los múltiple atributo en el archivo entrada elemento.
  • los FileReader objeto de la nueva API de archivos.
  • los FormData objeto de XMLHttpRequest2.

Usamos el múltiple atributo para permitir al usuario seleccionar múltiples archivos para cargar (la carga de múltiples archivos funcionará normalmente incluso si FormData no está disponible). Como veras, FileReader nos permite mostrar las miniaturas de los archivos que están cargando (esperaremos imágenes).

Ninguna de nuestras tres funciones funciona en IE9, por lo que todos los usuarios de IE obtendrán una experiencia de carga normal (aunque entiendo que el soporte para 'FileReader' está disponible en IE10 Dev Preview 2). FileReader no funciona en la última versión de Safari (5.1), por lo que no obtendrán las miniaturas, pero sí obtendrán la carga de AJAX y el mensaje de confirmación. Finalmente, Opera 10.50 tiene FileReader apoyo pero no FormData apoyo, por lo que obtendrán miniaturas, pero las subidas normales.

Con eso fuera del camino, vamos a obtener la codificación!


Paso 1: El marcado y el estilo

Vamos a empezar con algunas marcas básicas y el estilo. Por supuesto, esta no es la parte principal de este tutorial, no te trataré como un novato.

El HTML

    API de archivos HTML5    

Sube tus imágenes

Bastante básico, ¿eh? Tenemos un formulario que publica subir.php, que veremos en un segundo, y un solo elemento de entrada, de tipo expediente. Note que tiene el booleano. múltiple atributo, que permite al usuario seleccionar varios archivos a la vez.

Eso es realmente todo lo que hay que ver aquí. Vamonos.

El CSS

body font: 14px / 1.5 helvetica-neue, helvetica, arial, san-serif; relleno: 10px;  h1 margen superior: 0;  #main ancho: 300px; margen: auto; fondo: #ececec; relleno: 20px; borde: 1px sólido #ccc;  # lista de imágenes estilo de lista: ninguno; margen: 0; relleno: 0;  # lista de imágenes li fondo: #fff; borde: 1px sólido #ccc; text-align: center; relleno: 20px; margen inferior: 19px;  # image-list li img width: 258px; alineación vertical: medio; borde: 1px sólido # 474747; 

Absolutamente ninguna sorpresa aquí.


Paso 2: El PHP

Necesitamos poder manejar las cargas de archivos en el back-end también, así que vamos a cubrir eso a continuación.

subir.php

 $ error) si ($ error == UPLOAD_ERR_OK) $ nombre = $ _FILES ["images"] ["name"] [$ key]; move_uploaded_file ($ _FILES ["images"] ["tmp_name"] [$ key], "uploads /". $ _FILES ['images'] ['name'] [$ key]);   eco "

Imágenes cargadas con éxito

";

Tenga en cuenta que estas fueron las primeras líneas de PHP que escribí fácilmente en un año (soy un tipo Ruby). Probablemente deberías estar haciendo un poco más por seguridad; Sin embargo, simplemente nos aseguramos de que no haya errores de carga. Si ese es el caso, usamos el incorporado mover_archivo_subido moverlo a un subidas carpeta. No olvides asegurarte de que la carpeta sea de escritura..

Entonces, en este momento, deberíamos tener un formulario de carga de trabajo. Elige una imagen (múltiple, si lo desea y su navegador le permite), haga clic en ?Subir archivos!? botón, y recibe el mensaje ?Imágenes cargadas con éxito.?

Así es como se ve nuestro mini-proyecto hasta ahora:

Pero, vamos, es 2011: queremos más que eso. Notarás que hemos vinculado jQuery y un subir.js expediente. Vamos a abrir eso ahora.


Paso 3: El JavaScript

No perdamos tiempo: aquí vamos.!

(function () var input = document.getElementById ("images"), formdata = false; if (window.FormData) formdata = new FormData (); document.getElementById ("btn"). style.display = "none "; ();

Aquí es con lo que empezamos. Creamos dos variables: entrada es nuestro elemento de entrada de archivo; formdata se utilizará para enviar las imágenes al servidor si el navegador lo admite. Lo inicializamos a falso y luego verifica si el navegador soporta FormData; Si lo hace, creamos una nueva. FormData objeto. Además, si podemos enviar las imágenes con AJAX, no necesitamos "Cargar imágenes". Botón, para que podamos ocultarlo. ¿Por qué no lo necesitamos? Bueno, vamos a cargar automáticamente las imágenes inmediatamente después de que el usuario las seleccione..

El resto del JavaScript irá dentro de su función de auto-invocación anónima. A continuación, creamos una pequeña función de ayuda que mostrará las imágenes una vez que el navegador las tenga:

función showUploadedItem (source) var list = document.getElementById ("image-list"), li = document.createElement ("li"), img = document.createElement ("img"); img.src = fuente; li.appendChild (img); list.appendChild (li); 

La función toma un parámetro: la fuente de la imagen (veremos cómo lo obtendremos pronto). Luego, simplemente encontramos la lista en nuestro marcado y creamos un elemento e imagen de la lista. Establecimos la fuente de la imagen a la fuente que recibimos, colocamos la imagen en el elemento de la lista y colocamos el elemento de la lista en la lista. Voila!

A continuación, tenemos que tomar las imágenes, mostrarlas y cargarlas. Como hemos dicho, haremos esto cuando el onchange evento se dispara en el elemento de entrada.

if (input.addEventListener) input.addEventListener ("change", function (evt) var i = 0, len = this.files.length, img, reader, file; document.getElementById ("response"). innerHTML = "¿Cargando?" Para (; i < len; i++ )  file = this.files[i]; if (!!file.type.match(/image.*/))    , false); 

No tenemos que preocuparnos por el modelo de eventos patentado de IE, porque IE9 + admite la función addEventListener estándar.

Hay más, pero comencemos con esto. En primer lugar, no tenemos que preocuparnos por el modelo de eventos patentado de IE, porque IE9 + es compatible con el estándar addEventListener Función (y IE9 y abajo no son compatibles con nuestras nuevas funciones).

Entonces, ¿qué queremos hacer cuando el usuario ha seleccionado los archivos? En primer lugar, creamos algunas variables. El único importante en este momento es len = this.files.length. Los archivos que el usuario ha seleccionado serán accesibles desde el objeto esto.files. En este momento, sólo nos preocupa la longitud propiedad, por lo que podemos recorrer los archivos?

? que es exactamente lo que estamos haciendo a continuación. Dentro de nuestro bucle, configuramos el archivo actual a expediente para facilitar el acceso. Lo siguiente que hacemos es confirmar que el archivo es una imagen. Podemos hacer esto comparando el tipo Propiedad con una expresión regular. Estamos buscando un tipo que comienza con? Imagen? y es seguido por cualquier cosa. (El doble golpe en el frente simplemente convierte el resultado a un valor booleano).

Entonces, ¿qué hacemos si tenemos una imagen en nuestras manos??

if (window.FileReader) reader = new FileReader (); reader.onloadend = function (e) showUploadedItem (e.target.result); ; reader.readAsDataURL (archivo);  if (formdata) formdata.append ("images []", archivo); 

Verificamos si el navegador soporta la creación. FileReader objetos. Si lo hace, crearemos uno..

Así es como usamos un FileReader objeto: vamos a pasar nuestra expediente objetar al reader.readAsDataURL método. Esto crea una url de datos para la imagen cargada. Sin embargo, no funciona de la manera que se podría esperar. La url de datos no se devuelve de la función. En su lugar, la url de datos será parte de un objeto de evento..

Con esto en mente, tendremos que registrar una función en el reader.onloadend evento. Esta función toma un objeto de evento, mediante el cual obtenemos la url de datos: está en e.target.result (sí, e.target es el lector objeto, pero tuve problemas al usar lector en lugar de e.target dentro de esta función). Solo vamos a pasar esta url de datos a nuestro showUploadedItem función (que escribimos arriba).

A continuación, comprobamos la formdata objeto. Recuerda, si el navegador soporta FormData, formdata será un FormData objeto; de lo contrario, será falso. Entonces, si tenemos un FormData objeto, vamos a llamar a la adjuntar método. El propósito de un FormData objeto es mantener los valores que está enviando a través de un formulario; entonces el adjuntar El método simplemente toma una clave y un valor. En nuestro caso, nuestra clave es imagenes []; añadiendo los corchetes al final, nos aseguramos de que cada vez que adjuntar otro valor, en realidad lo estamos agregando a esa matriz, en lugar de sobrescribir el imagen propiedad.

Ya casi hemos terminado. En nuestro bucle for, hemos mostrado cada una de las imágenes para el usuario y las hemos agregado a la formdata objeto. Ahora, solo tenemos que subir las imágenes. Afuera de para bucle, aquí está la última pieza de nuestro rompecabezas:

if (formdata) $ .ajax (url: "upload.php", escriba: "POST", datos: formdata, processData: false, contentType: false, success: function (res) document.getElementById ("response" ) .innerHTML = res;); 

Una vez más, tenemos que asegurarnos de que tenemos FormData apoyo; Si no lo hacemos, los archivos "Subir archivos!" El botón será visible, y así es como el usuario cargará las fotos. Sin embargo, si tenemos FormData Soporte, nos encargaremos de subirlo vía AJAX. Estamos usando jQuery para manejar todas las rarezas de AJAX en todos los navegadores.

Probablemente estés familiarizado con jQuery. $ .ajax Método: se le pasa un objeto de opciones. los url, tipo, y éxito Las propiedades deben ser obvias. los datos la propiedad es nuestra formdata objeto. Fíjate en esos procesar datos y tipo de contenido propiedades Según la documentación de jQuery., procesar datos es cierto de forma predeterminada, procesará y transformará los datos en una cadena de consulta. No queremos hacer eso, así que configuramos esto falso. También estamos estableciendo tipo de contenido a falso para asegurarnos de que los datos lleguen al servidor como esperamos.

Y eso es. Ahora, cuando el usuario carga la página, ven esto:

Y después de seleccionar las imágenes, verán esto:

Y las imágenes han sido subidas:


Eso es un envoltorio!

Cargar archivos a través de AJAX es bastante bueno, y es genial que estas nuevas tecnologías lo admitan sin la necesidad de hacks largos. Si tienes alguna pregunta sobre lo que hemos hecho aquí, ¡haz clic en esos comentarios! Muchas Gracias Por Leer!

Y si aún necesita ayuda con este o cualquier otro problema de codificación, encuentre soporte en Envato Studio.

Aprender JavaScript: la guía completa

Hemos creado una guía completa para ayudarlo a aprender JavaScript, ya sea que esté comenzando a trabajar como desarrollador web o si desea explorar temas más avanzados.