viernes 16 de octubre de 2009

Subir archivos sin componentes en ASP con Xelupload

Quieres subir ficheros al servidor mediante un formulario, con uno o varios campos de tipo FILE, pero no puedes utilizar ASPUpload, no quieres pagarlo o no puedes registrar componentes. Aquí tienes una completa solución de upload de ficheros, escrita 100% en ASP y VBScript.

Introducción

Subir ficheros al servidor mediante un formulario es una opción que nos brinda HTML muy poderosa, en
cuanto que nos permite crear aplicaciones web más completas: podemos hacer nuestro propio sistema
de FTP casero, vía web, podemos dejar a nuestros colaboradores que suban sus imágenes, etc. todo
a través de una página web.
Lamentablemente, ASP no nos proporciona un mecanismo automático para procesar este tipo de envíos. Por esto,
se hace necesario extender el entorno ASP, bien con productos comerciales como ASPUpload y SA-FileUp, o bien
escribiendo nuestro propio programa.
El problema de utilizar componentes, ya sean propios o comprados (o pirateados... ¿quién ha dicho eso?) es
que en muchos planes de alojamiento no nos es posible registrar estos componentes. En estos casos, la única
solución es programarlo mediante puro código ASP, y eso es lo que he hecho.


Requerimientos

xelUpload es el nombre de una clase de VBScript que presenta propiedades y métodos para manejar
el envío de ficheros al servidor. Su único requerimiento es disponer de la versión 5 o superior del motor de script. Para ver
qué versión tienes disponible, puedes escribir:
Response.Write ScriptEngineMajorVersion
Si ves un 5, todo es correcto. Si no, puedes descargar gratis la última versión desde el sitio de Microsoft sobre script, o instalar Internet Explorer 5 o
superior, que la incluye entre sus ficheros.
Por si no lo sabíais, para que el fichero llegue correctamente al servidor, tenemos que añadir un atributo más a la marca FORM, el que especifica la codificación del formulario al enviarlo, y nos permite subir datos binarios, así:
<form action="pagina.asp" method="post" enctype="multipart/form-data">

Cómo se usa

¿Cómo funciona xelUpload? Lo primero que tenemos que hacer es incluir el fichero, mediante:
<!--#include file="xelupload.asp"-->
si está el mismo directorio o
<!--#include virtual="/includes/xelupload.asp"-->
si está en otra ruta virtual, en este caso, en /includes/.
Después, debemos crear una instancia del objeto, y llamar al método Upload para comenzar
el proceso en la página que recibe el formulario.
<%Dim objUploadobjUpload.Upload()%>
El objeto xelUpload, una vez llamado su método Upload, guardará los ficheros enviados con el formulario en la colección Ficheros, y los campos de texto normales en la colección eltosForm. La primera contiene objetos de tipo Fichero, que es otra clase que también incluyo, y a los elementos de la segunda se
puede acceder con objUpload.Form("campo"), que es bastante familiar. ;-)
Para saber el número de ficheros subidos correctamente, podemos utilizar:
Response.Write objUpload.Ficheros.Count & " ficheros subidos."
Para acceder a las propiedades y métodos de cada Fichero subido, podemos recorrer la colección, o bien acceder directamente a uno, con el nombre del campo INPUT que tuviera el formulario:
Dim objUpload, objFicheroobjUpload.Upload()'si teníamos <input type="file" name="imagen">set objFichero = objUpload.Ficheros("imagen")'recorremos todos:for each objFichero in objUpload.Ficheros.Items...next
NOTA: El fichero ZIP con el código, documentación y un ejemplo está disponible al final del artículo.

Propiedades y métodos

Para ver en detalle qué podemos hacer con los ficheros una vez subidos, veamos qué nos ofrece la clase xelUpload y la clase Fichero, respectivamente:
xelUpload
Propiedades
Form(nombrecontrol)
Devuelve el campo del formulario de nombre "nombrecontrol". Equivale completamente a Request.Form(nombrecontrol).
Métodos
Upload
Realiza el proceso de recepción del formulario y
almacena los resultados. Es imprescindible
llamar a este método antes de acceder a las
demás propiedades o colecciones del objeto
xelUpload.
Colecciones
Ficheros
Contiene una colección de objetos Fichero, uno por cada fichero enviado correctamente desde el formulario.
Fichero
Propiedades
Nombre
Devuelve el nombre original del fichero, sin la ruta en el disco del usuario. Por ejemplo, mickeymouse.gif.
Tamano
Devuelve el tamaño en bytes del fichero.
TipoContenido
Devuelve el tipo de contenido del fichero en una cadena, si es reconocido por el servidor, o bien "application/octet-stream". Por ejemplo, para la imagen anterior, devolvería "image/gif".
Datos
Devuelve los datos binarios puros del fichero.
Métodos
Guardar ruta
Salva el fichero en disco en el servidor, con el nombre original, en la ruta pasada como argumento. Debe ser una ruta física, no virtual, así que probablemente utilizaremos Server.MapPath, así:

objFichero.Guardar (Server.MapPath("\upload"))
GuardarComo nombre, ruta
Salva el fichero en disco, con el nombre especificado, en la ruta especificada. El nombre debe ser un nombre de fichero válido y la ruta, una ruta física.
GuardarBD objFld
Guarda el contenido del fichero en el objeto Field de ADO pasado como argumento. Más abajo os explico cómo hacer esto.


Como ves, la interfaz es bastante flexible. Como siempre, todo esto se ve mejor con un ejemplo, así que vamos a ello.
Supongamos que enviamos un formulario como este:
<form action="pagina.asp" method="post" enctype="multipart/form-data">Nombre: <input type="text" name="usuario" size="20"><br>Edad: <input type="text" name="edad" size="5"><br><input type="file" name="imagen"><br><input type="submit" value="Enviar"></form>
En la página que lo recibe y que hemos especificado en el atributo ACTION, pagina.asp, utilizamos nuestro superpoderoso y versátil xelUpload (se nota que estoy contento, ¿eh?) para ver el tipo de fichero que nos envía y su tamaño. Si es una imagen GIF y no supera los 15k (15*1024 bytes), la guardamos en dos directorios distintos (vale, esto no será muy normal, pero tengo que ilustrar los métodos) y en una base de datos, en una hipotética tabla usuarios que guarda (¿puedes imaginarlo?) el nombre, la edad, y una imagen GIF (supuestamente del usuario, aunque en GIF y menos de 15k... ¡ejem!).
No vamos a guardar sólo el nombre del fichero: vamos a guardar la imagen completa en una base de datos Access.

Este es el código de nuestra página que recibe el formulario
<%'pagina.asp%><!--#include file="xelupload.asp"--><%Dim oConn, rs, SQLDim objUpload, objFich, strNombre, strEdadDim maxtam, strNombreFichero'nuestro tamaño máximomaxtam = 15 * 1024set objUpload = new xelUploadobjUpload.Upload()'recuperamos los campos usuario y edadstrNombre = objUpload.Form("usuario")strEdad = objUpload.Form("edad")'si no ha subido ningún fichero, le avisamosif objUpload.Ficheros.Count = 0 thenResponse.Write("¡No has subido ningún fichero!")else'accedemos al fichero por su nombre en el formularioset objFich = objUpload.Ficheros("imagen")if objFich.Tamano <= maxtam and objFich.TipoContenido = "image/gif" then'Es el fichero correcto, vamos a guardarlo en todas partes. :-)'Primero, en nuestro directorio actual con el nombre que tieneobjFich.Guardar Server.MapPath(".")'Ahora, en el directorio upload, con la fecha de hoy como nombrestrNombreFichero = Day(Date) & Month(Date) & Year(Date)objFich.GuardarComo strNombreFichero, Server.MapPath("upload")'Ahora nos conectamos a una base de datosset oConn = Server.CreateObject("ADODB.Connection")set rs = Server.CreateObject("ADODB.Recordset")'Nos conectamos con ODBC sin DSN, suponiendo que la base'de datos está en este mismo directoriooConn.Open "Driver={Microsoft Access Driver (*.mdb)};" _& "DBQ=" & Server.MapPath("usuarios.mdb")SQL = "SELECT * FROM usuarios"'Abrimos el Recordset: el 0 es el cursor adForwardOnly' y el 2 es el cerrojo adLockPessimisticrs.Open SQL, oConn, 0, 2'Añadimos un nuevo registrors.AddNewrs.Fields("Nombre") = strNombrers.Fields("Edad") = strEdadrs.Fields("NombreFichero") = objFich.Nombre'Llamamos a GuardarBD pasandole el campo correspondiente!!!objFich.GuardarBD rs.Fields("Imagen")'Guardamos el nuevo registrors.Update'y limpiamos todo que vienen los padresrs.Closeset rs = nothingoConn.Closeset oConn = nothing'¡Todo correcto!Response.Write "Se ha añadido el nuevo usuario <b>" & strNombre & "</b>, "  _& "con el fichero " & objFich.Nombre & " de tamaño " & objFich.Tamano & "."'Limpiamos nuestro xelUpload y el ficheroset oFich = nothingset objUpload = nothingelse'No era un fichero válidoResponse.Write("No es un fichero aceptable. ")Response.Write("Tiene que ser un fichero GIF de menos de 15k.")end ifend if%>
En este código véis todas las posibilidades que ofrece xelUpload. La tabla usuarios que utilizamos tiene esta estructura:
Nombre del campo
Tipo de datos
ID_Usuario
Autonumérico
Nombre
Texto
Edad
Texto
NombreFichero
Texto
Imagen
Objeto OLE


Como véis, Objeto OLE es el tipo que acepta datos binarios en Access. En SQL Server el equivalente es image, que es de tipo binario y acepta más de 8.000 bytes, o binary si guardamos menos de 8.000 bytes.

Observaciones, notas, etc

Hay una restricción importante del objeto Request, que hace imprescindible incluir el manejo de los campos normales de un formulario dentro del programa que maneje los ficheros subidos: que después de utilizar Request.BinaryRead no se puede utilizar Request.Form y viceversa. Así que tenéis que utilizar la propiedad Form de vuestro objeto xelUpload para leer los campos habituales de un formulario.

Fuente: AspFacil
Archivo: Xelupload

xelupload.zip

Etiquetas: , , ,


This page is powered by Blogger. Isn't yours?

Suscribirse a Entradas [Atom]