Tutorial de SWFUpload, uploads via web utilizando Macromedia Flash

DISCLAIMER

Lo que sigue a continuación roza peligrosamente el concepto de ladrillo, si no te interesa el desarrollo web en general, y las soluciones de upload en particular, para de leer inmediatamente. Avisado quedas.

ABSTRACT

SWFUpload es una pequeña aplicación Flash controlable via Javascript que nos permite realizar uploads de ficheros en nuestros formularios web.

DEMO Y DESCARGA

En la propia web del programa: http://labb.dev.mammon.se/swfupload/

Demo de mi propia (y minimalista... y sucia...) implementación: http://www.propiedadprivada.com/lab/swfupload/

TUTORIAL: CARACTERÍSTICAS

Contra el tradicional input file o sus múltiples implementaciones en Java, SWFUpload nos ofrece varias ventajas importantes:

  • Permite limitar los tipos de archivo a subir (p.e. *.jpg,*.gif)
  • Permite la subida simultánea de múltiples archivos (Seleccionando en el diálogo con Control/Mayúsculas + Click)
  • Permite control de eventos JS programables para inicio, cancelación, progreso y completado del upload
  • Permite controlar desde JS información sobre el fichero (como Tamaño, nombre, etc...) antes de iniciar el upload
  • Permite dar el estilo que queramos al botón de upload, utilizando imágenes y rollovers
  • Permite generar barras de progreso con XHTML y CSS válidos
  • Permite informar sobre el estado de la subida sin necesidad de recargar nada en el navegador
  • Permite realizar todo esto en todo tipo de combinaciones de sistema operativo/navegador que soporte Flash
  • Permite degradar sin problemas en navegadores sin Javascript o Flash

TUTORIAL: CÓMO LO HACEN

Gracias a la nueva clase flash.net.FileReference, podemos gestionar desde Flash el envío (y descarga) de archivos por medio de nuestro objeto Flash. Para ello la mencionada clase abre la caja nativa del sistema operativo para escoger un archivo y luego enviarlo al servidor.

Por medio de la librería SWFObjec, SWFUpload detecta el plugin Flash del cliente, degradando en un formulario HTML normal en caso de no detectarlo, y escribiendo el HTML necesario para embeber un objeto Flash en caso afirmativo.

Este objeto Flash hace uso de la mencionada clase flash.net.FileReference (lo cual impone automáticamente como requerimiento Flash 8) y nos proporciona una "puerta" de acceso desde Javascript a las funciones contenidas en la misma.

Para implementarlo seguiremos estos sencillos pasos....

HTML:
  1. Incluimos el archivo de la libreria:
  2. <script type="text/javascript" src="mmSWFUpload.js"></script>
  3.  
  4. Creamos una capa contenedora para el objeto Flash:
  5. <div id="SWFUpload">Aqui pondríamos el formulario de
  6.  upload normal, para clientes que carezcan del plugin
  7.  Flash o Javascript, podemos hacerlo sin miedo porque
  8.  si todo va bien el contenido de esta capa será
  9.  sobreescrito por SWFUpload</div>
  10.  
  11. E iniciamos el objeto:
  12. <script type="text/javascript">
  13. mmSWFUpload.init({
  14.   upload_backend : "http://www.url.com/upload.php",
  15.   target : "SWFUpload",
  16. });
  17. </script>

Botón SWFUploadNótese que como destino del objeto Flash indicamos la ID de la capa contenedora antes creada: SWFUpload en este caso. Por su parte, la variable upload_backend indica la url del archivo que va a gestionar dicho upload una vez enviado al servidor por nuestra pequeña aplicación Flash.

Una vez embebido, tan sólo veremos como área pulsable la imagen que hayamos elegido a tal efecto.

TUTORIAL: CÓMO IMPLEMENTARLO

Una vez pulsada la imagen definida para SWFUpload, se nos presentará un cuadro de diálogo para seleccionar archivos, cuadro configurable por medio de una variable (p.e. allowed_filetypes : "*.gif;*.jpg;*.png", ) que definirá los tipos de archivo aceptados.

SWFUpload allowed_filetypes

Según vayamos interactuando con el objeto Flash por medio de Javascript, se irán disparando los eventos que este tiene configurados:

  • upload_start_callback : 'Funcion_JS_que_controla_el_inicio_del_upload',
  • upload_progress_callback : 'Funcion_JS_que_controla_el_progreso_del_upload',
  • upload_complete_callback : 'Funcion_JS_que_controla_el_completado_del_upload',
  • upload_error_callback : 'Funcion_JS_que_controla_los_posibles_errores',
  • upload_cancel_callback : 'Funcion_JS_que_controla_el_cancelado_de_selección_de_archivo'

Veamos un pequeño ejemplo más "afinado" a nuestro gusto:

JAVASCRIPT:
  1. <script type="text/javascript">
  2. mmSWFUpload.init({
  3.      upload_backend : "../../upload.php",
  4.      button_image : "images/custom_button.png",
  5.      button_mouseover_image : "images/custom_button_over.png",
  6.      width : "258px",
  7.      height : "82px",
  8.      target : "SWFUpload",
  9.      allowed_filetypes : "*.gif;*.jpg;*.png",
  10.      upload_start_callback : 'uploadStart',
  11.      upload_progress_callback : 'uploadProgress',
  12.      upload_complete_callback : 'uploadComplete',
  13.      upload_error_callback : 'uploadError',
  14.      upload_cancel_callback : 'uploadCancel'
  15. });
  16.  
  17. </script>

Aparte de lo comentado más arriba, las propiedades se explican sólas. La mayoría son incluso opcionales, pero si queremos algo minimamente personalizado disponemos de varias formas de llamar a Javascript para mostrar la información.

Todos los callbacks realizados desde el objeto Flash devuelven además un objeto imagen, que contiene el nombre del archivo, su tamaño y su extensión, para que podamos jugar con el mismo sin problema. Su apariencia es algo así:

JAVASCRIPT:
  1. fileObj.name = filename (archivo.png)
  2. fileObj.size = filesize (192912)
  3. fileObj.type = filetype (.png)

La función upload_progress_callback devuelve además los bytes ya enviados al servidor, para poder seguir su progreso.

Veamos unos ejemplos de uso de las funciones callback:

uploadStart, controlar el momento en que se inicia el Upload

JAVASCRIPT:
  1. uploadStart = function(fileObj) {
  2.     var container = document.getElementById("fileContainer");
  3.     container.innerHTML += "<span id='" + fileObj.name + "'>";
  4.     container.innerHTML += fileObj.name + ", ";
  5.     container.innerHTML += fileObj.size + ", ";
  6.     container.innerHTML += fileObj.type + "</span><br />";
  7. }

uploadProgress, controlar el progreso del upload.

JAVASCRIPT:
  1. uploadProgress = function(fileObj, bytesLoaded) {
  2.     var pie = document.getElementById("progressInfoElm");
  3.     var proc = Math.ceil((bytesLoaded / fileObj.size) * 100);
  4.     pie.innerHTML = proc + " %";
  5. }

uploadComplete, controlar el momento en que nuestro upload se completa

JAVASCRIPT:
  1. uploadComplete = function(fileObj) {
  2.     document.getElementById(fileObj.name).className = "uploadDone";
  3.     document.getElementById(fileObj.name).innerHTML = objFile.name + " done!";
  4. }

uploadError, gestionar posibles errores en el upload. Incluso en esto SWFUpload es rico en información, tanto en el tipo de error como en la descripción del mismo, pasándonos desde códigos de error propios a los típicos de HTTP.

JAVASCRIPT:
  1. uploadError = function(error,errorFile,errorCode) {
  2.   switch(error) {
  3.      case -10:
  4.      cadena="Error de HTTP , contacte con el servicio técnico e indíquele este código de error: " + errorCode;
  5.      break;
  6.      case -20:
  7.      cadena="Error, no se ha especificado fichero de destino";
  8.      break;
  9.      case -30:
  10.      cadena="Error de E/S, contacte con el servicio técnico";
  11.      break;
  12.      case -40:
  13.      cadena="Error de violación de seguridad, contacte con el servicio técnico";
  14.      break;
  15.      }
  16.   alert("Error subiendo el archivo: " + errorFile.name + "\n\n" + cadena);
  17. }

TUTORIAL: BUGS Y LIMITACIONES

Si estás utilizando Apache con mod_security activado esta solución no funcionará, necesitarás incluir esto en un archivo .htaccess para desactivar el mod_security:

JAVASCRIPT:
  1. SecFilterEngine Off
  2. SecFilterScanPOST Off

Cuidado Deshabilitar mod_security no está permitido en la mayoría de los alojamientos compartidos, y aún si está permitido documéntate acerca de las implicaciones que conlleva antes de hacer nada.

Este comportamiento anómalo se debe a un bug en la forma que Flash envía las cabeceras de vuelta al servidor, tal y como se explica en la documentación de Flash 8

AGRADECIMIENTOS Y LICENCIA

Un gran "gracias" a Geoff Stearns pos su SWFObjec, sin el cual este pequeño experimento no habría sido ni la mitad de bueno. Podeis verlo en su web original: http://blog.deconcept.com/swfobject

SWFUpload está protegido por (c) 2006 Lars Huring - Profandesign y Mammon Media y se lanza al público bajo licencia MIT: http://www.opensource.org/licenses/mit-license.php

El que suscribe agradece a Chesterfield y Cafés Candelas el apoyo recibido en la redacción y traducción del presente folleto parroquial.

CONCLUSION

Los que me conocen saben que por lo general aborrezco el Flash por encima de todas las cosas (salvo quizá la política y la prensa del corazón), sin embargo he de reconocer que estamos ante un gran ejemplo de "buen" uso de Flash, cuando éste puede hacer un mejor trabajo que un simple HTML, en vez de usarlo para pintar monas y atormentar nuestros oídos.

Asimismo, en esta época tan "Web 2.0", SWFUpload hace una perfecta demostración de trabajo no intrusivo, sin un requerimiento real del plugin Flash.

Por mi parte, Chapeau.

Términos relacionados: , , , , ,

21 comentarios a esta entrada

  • mimo dijo
    el # Sábado, 16 de Diciembre del 2006 a las 14:18

    1

    I have a question, is it posibile to integrate it with asp? I’m looking for a way to write down names uploaded files in local DB..

    Thank you, Good job!

  • Marcos B.L. dijo
    el # Sábado, 16 de Diciembre del 2006 a las 23:11

    2

    SWFUpload is just a gateway to upload the files, using the upload_backend variable you can set for example:

    upload_backend=`script_that_saves_file_to_disk_or_database.asp`

    with no problem at all.

    Than you write normal ASP code to write file data (name, size, etc…) or the file itself to database or disk, but that goes out of the scope of this little tutorial.

    Hope that helps a bit.

  • d23 Gaston dijo
    el # Miércoles, 27 de Diciembre del 2006 a las 21:49

    3

    Hola, queria saber como se hace para que solo se pueda suber de a un arcivo solo nomas..muchas grasias y exelente expermento. :D

  • Gustavo dijo
    el # Jueves, 4 de Enero del 2007 a las 07:52

    4

    El script no me funciona, lo probé en dos servers diferentes y no anda. Se despliega el cuadro de diálogo pero al elegir los archivos no me dice nada, no hace nada. La segunda vez que hago lo mismo me da el mensaje “Queue Done!” pero nunca sube nada, ni siquiera muestra los archivos y la barra de progreso, nada. Probé con el index que trae, hice uno nuevo, cambie de directorio al index, etc pero siempre hace lo mismo. Tengo todo en 777 y descomenté el upload.php. Que puede estar fallando?

  • Marcos B.L. dijo
    el # Jueves, 4 de Enero del 2007 a las 09:32

    5

    d23Gaston, simplemente oculta la capa que contiene el botón tras la primera subida, y añade tus acciones (por ejemplo refrescar a otra página) al finalizar la primera subida.

    Gustavo, puedes ponernos la url de pruebas que estás usando, para poder darle un ojo ?

  • Gustavo dijo
    el # Viernes, 5 de Enero del 2007 a las 08:55

    6

    http://www.imagenshare.com.ar/prueba/index.php esa es la de prueba. Solucioné el tema de que muestre las barras de progreso, pero ahora muestra todos los archivos que se van a cargar, muestra la barra del primero y después se queda estático. No sube nada al server pero sí chequea el archivo “upload.php” porque me genera el directorio “files”. Copie el example.js de la web del autor, el que esta usando el ejemplo.

    Saludos y gracias.

  • joxxxe dijo
    el # Martes, 9 de Enero del 2007 a las 04:28

    7

    oye gustavo yo stoy igual que tu no puedo subir nada ya descomente el upload.php pero ahora no se no me va

    no entiendo hacen un plugin tan hermoso no pueden hacer un mejor manual … disculpen mi atrevimiento pero muchos tenemos problemas implementado esto , gracias

  • pablasso dijo
    el # Miércoles, 10 de Enero del 2007 a las 09:19

    8

    una lastima que no funcione con flash 7, los usuarios de linux tendremos que esperar a que adobe saque la version 8 o 9 abierta.. a buscar otra solucion

  • Marcos B.L. dijo
    el # Jueves, 11 de Enero del 2007 a las 17:52

    9

    ahora muestra todos los archivos que se van a cargar, muestra la barra del primero y después se queda estático

    Gustavo, revisa el código javascript, esto es debido a que todas las descargas del array se llaman igual, prueba el código de mi ejemplo a ver si te va mejor

    no pueden hacer un mejor manual … disculpen mi atrevimiento pero muchos tenemos problemas implementado esto

    joxxxe, yo no he creado el plugin y, de hecho, no tengo nada que ver con los creadores, si el manual que he hecho no te sirve, lo lamento profundamente, es lo mejor que he podido/sabido hacer, intenta si acaso… contactar con los autores en todo caso.

    una lastima que no funcione con flash 7, los usuarios de linux tendremos que esperar a que adobe saque la version 8 o 9 abierta

    pablasso, no te falta razón, pero tienes la beta 2 de Flash Player 9 para Linux, como puedes ver en:
    http://labs.adobe.com/downloads/flashplayer9.html
    Instalador para linux:
    http://www.adobe.com/go/fp9_update_b2_installer_linuxplugin
    Versión Standalone:
    http://www.adobe.com/go/fp9_update_b2_standalone_linux

    Espero que te sirva.

  • rosele dijo
    el # Sábado, 3 de Febrero del 2007 a las 01:33

    10

    Hola, comento lo que ya han dicho otros.

    No sume nada al servidor, a que es debido?

    Tu tutorial esta muy bien explicado. Gracias y enhorabuena

  • Marcos B.L. dijo
    el # Sábado, 3 de Febrero del 2007 a las 03:13

    11

    El problema de que no os suba nada no es del lado del SWF (siempre y cuando os muestre el progreso) Teneis que crear un upload.php en su misma carpeta con las instrucciones necesarias para colocar el archivo subido donde quereis.

    En otras palabras, el SWF si está subiendo el fichero al servidor, y el servidor lo recibe (normalmente en una carpeta interna /tmp o /temp) pero vosotros no lo cogeis de ahi y lo meteis en su lugar correspondiente.

    Si lo considerais interesante, os puedo hacer un pequeño artículo sobre como hacer esto. Ya me comentareis.

  • fbarrera dijo
    el # Miércoles, 14 de Febrero del 2007 a las 23:20

    12

    tengo un problema con la el tamaño de los archivos.
    me sube hasta mas o menos 2000 kb solamente

    despues no pasa nada, le puse: allowed_filesize : “1000000″,
    y necesito realmente que pase esa cantidad por mucho.

  • Marcos B.L. dijo
    el # Jueves, 15 de Febrero del 2007 a las 11:48

    13

    Si tienes un servidor propio, o acceso al php.ini, o se te permite modificar el comportamiento del php .htaccess, estás de suerte, si no, estás jodido. Mayormente ese límite de dos megas no viene impuesto por SWFUpload en absoluto, sino por el propio hosting, que tiene limitado el tamaño de upload a 2 Mb, enterate lo primero si puedes hacer modificaciones en el php.ini de tu hosting o si te permiten utilizar .htaccess para ello. Si es así, basta con que configures el tamaño máximo de subida a lo que tú quieras en el php, para que puedas realizar tus uploads.

    Date cuenta que el allowed_filesize que le indicas a SWFUpload sólo limita el tamaño de los archivos a subir del lado del cliente, del navegador, vamos, pero ese problema que me indicas es del lado del servidor: te pasaría exactamente lo mismo si en vez de subir los ficheros con SWFUpload lo hicieses desde un formulario HTML, lo que tienes que subir es el límite de upload del lado del servidor.

    Vete probando estos valores en tu php.ini (Generalmente está en /etc/php.ini, seguramente tendrás que reiniciar Apache tras cada cambio). Pongamos por ejemplo un límite de archivo de 16Mb:

    file_uploads = On
    max_execution_time = 120 // los segundos que creas que puede tardar el script en tratar el fichero, no el cliente en subirlo, también puedes ponerlo a 0 para -sin limite-
    max_input_time = 120 // Idem
    memory_limit = 32M // recomendaría, siempre que sea posible, el doble del archivo máximo que quieras subir
    post_max_size = 16M // el tamaño máximo del archivo a subir
    upload_max_filesize = 16M // Idem

    Si con esto aún no te funciona (extraño), puedes probar a tocar tambien el conf.d/php.conf dentro de tu carpeta de configuración de Apache, añadiendo esto (añade además un < antes de la 1ª y 3ª lineas, el puñetero wordpress se empeña en no dejarme escribir código en condiciones xE):

    files *.php>
    LimitRequestBody 16777216 // Para unos 16 Mb (16×1024x1024)
    /files>

    Si no tienes acceso al php.ini pero si al .htaccess coméntalo y te explico cómo hacerlo de esa forma.

    Ya nos contarás.

  • Lunicryster dijo
    el # Lunes, 19 de Febrero del 2007 a las 23:50

    14

    A mi tampoco me sube nada, aparece todo correcto pero después no sube nada.

    Por favor comenta lo del .htaccess Marcos.B.L

    Un saludito ;)

  • angel dijo
    el # Lunes, 26 de Marzo del 2007 a las 17:11

    15

    Buenas, me gustaría probar el sistema, me parece muy interesante, la pregunta es:

    ¿Como se utiliza esto en asp?

    Por lo que he leido, parece que está hecho para php.

    Saludos

  • Marcos B.L. dijo
    el # Lunes, 26 de Marzo del 2007 a las 17:53

    16

    Como veo que siguen surgiendo dudas acerca de este tema, mejor me hago un tutorial aparte explicando cómo funcionan los uploads del lado del servidor y os lo pongo. Pero si, se puede usar SWFUpload con php, asp, jsp y loqueseap, es un applet del lado del cliente que lo único que hace es enviar los datos al servidor, donde estais teniendo problemas todos es en tratarlos DEL LADO del servidor.

    A ver si con un pequeño tuto os queda un poco más claro, lo subiré lo antes posible.

  • pablo dijo
    el # Miércoles, 2 de Mayo del 2007 a las 17:27

    17

    ojo con d23gaston
    roba cosas de internet y dice que la hizo el
    no sabe nada de nada

  • angel dijo
    el # Jueves, 10 de Mayo del 2007 a las 18:04

    18

    A ver si me pueden echar un cable, please.

    Encontré un ejemplo para hacerlo en asp.net, lo único que no soy capaz es de realizar el upload.aspx, que lo suba donde yo kiero.

    Por si a alguien le interesa el ejemplo lo encontré en: http://www.4shared.com/file/13389186/472cab99/swfupload_vR41.html

    Espero una pronta respuesta.
    Gracias.

  • josuedavid dijo
    el # Miércoles, 22 de Agosto del 2007 a las 00:36

    19

    Hola, mira no se si podrian ayudarme con script en ASP clasico (no ASP.NET) para el upload de archivos con el SWFObject, Saludos, gracias

  • gino dijo
    el # Lunes, 22 de Octubre del 2007 a las 06:47

    20

    Hola Marcos por favor si fueras tan amable de decirme donde puedo conseguir el upload.php el tuto me funciona bien pero no logro ver las imagenes en el servidor donde los subo ya que como tu dices solo se queda en el tmp. desde ya muchas gracias.

  • Boletaire dijo
    el # Lunes, 19 de Mayo del 2008 a las 00:06

    21

    A mi me pasa igual, mi nivel de programación PHP no es muy elevado (puedo modificar y añadir ciertas cosas…) y he probado con el ejemplo de esta web:
    http://www.vb-mundo.com/SWFUpload-20-Subiendo-Archivos-Multiples-con-AJAX.asp

    pero no me funciona :S

    y cómo han dicho más arriba, es cierto que debería haber un mejor tutorial, pero no por tu parte sino por parte de la comunidad de SWFUpload..!!

Deja tu opinión

Sólo se permiten las etiquetas XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post anteriores/siguientes:

Post (quizás) relacionados:

  • Windows exe launch from html

  • O como romperse la cabeza con cosas que supuestamente no pueden hacerse. Problema 1 El tema es que tengo que lanzar varios exes (demos creadas con...
  • La Web 2.0

  • Canal de IRC ##php en freenode: dsully> tio.. a ver si puedes explicarme eso de la web 2.0 en un par de frases... jwb> viene siendo esto:...
  • Buenos usos de Flash

  • Si tu web no necesita promoción porque ya es conocida, o bien porque la reseñas machaconamente en la papelería de tu empresa, puede que el...
  • Web 2.0 … The Machine is Us/ing Us

  • Una de las más inspiradas formas que he visto hasta la fecha de definir la Web 2.0 Por mucho que hayas leido acerca del tema, merece...
  • De link varia

  • Back to School with the Class of Web 2.0 partes Uno, Dos y Tres es una cuidada recopilación de SolutionWatch de recursos útiles en Internet...