11/1/07

Subir ficheros con AJAX

De lo que he visto por ahí la mejor biblioteca de javascript es prototype. La llevo usando desde la versión 1.3 y la verdad es que va de lujo. Es cierto que en las siguientes versiones ha crecido quizá por encima de lo deseable, pero sigue siendo la mejor.

Para enviar datos de formularios utiliza la función encodeURIComponent, que es perfecta para todos los tipos de campo, excepto para los ficheros. Estaría bien que codificara el fichero, pero supongo que por razones de seguridad no lo hace.

Para poder hacerlo tenemos que recurrir a otra "versión de AJAX", que no es con el objeto XMLHttpRequest, sino con el tradicional uso de IFRAMES ocultos.

Aquí van los pasos a seguir

1. Creamos un IFRAME oculto que va a ser nuestro "objeto de entrada / salida":

var frameId='frameId',f;
if(window.ActiveXObject) //en IE hay que hacerlo así
{
f=document.createElement('<iframe id="' + frameId + '" name="' + frameId + '">');
f.src='javascript:false';
}
else
{
f=document.createElement('iframe');
f.id=frameId;
f.name=frameId;
}
f.style.position = 'absolute';
f.style.top = '-1000px';
f.style.left = '-1000px';
document.body.appendChild(f);


2. Creamos un FORM, redirigiendo la salida al IFRAME y le añadimos el input de tipo FILE

var f=document.createElement('form');
f.action=url;
f.method='POST';
f.target=frameId;
if(f.encoding)
f.encoding='multipart/form-data';
else
f.enctype='multipart/form-data';
f.style.position = 'absolute';
f.style.top = '-1000px';
f.style.left = '-1000px';

input.name='file';
f.appendChild(input);
document.body.appendChild(f);


3. Disparamos el método submit() del FORM
f.submit();

Si queremos comprobar qué nos devuelve el servidor cuando le enviamos el fichero tendríamos que añadir una función de respuesta cuando se cargara el IFRAME.

Haciéndolo un poco más orientado a objetos me he creado una clase Ajax.FileUpload para usarla como si fuera parte de la biblioteca prototype

Hay que tener en cuenta que uso un input que ya tengo en la página y que cuando envíe el fichero ya no lo voy a usar para nada más. El problema es que los inputs de tipo file tienen una serie de limitaciones de seguridad. Por ejemplo, en IE no se les puede asignar el atributo value, con lo cual estás vendido, además cuando los intentas clonar, no te copia el value del input original. Sólo te quedan dos opciones: o lo que hago yo que es usar el input original, o bien como se hace en el google page creator y en el correo yahoo, que es crear el form al generar la página, y posicionarlo donde te interesa.

No hay comentarios: