Contenido

Firefox3 integra opción nativa para gestionar la subida de ficheros

8 Jul

+ 3

Una de las nuevas funcionalidades de Firefox3 es la extensión de los elementos <input type="file" /> que nos permite utilizarlos previamente antes de subirlos a nuestro servidor mediante Javascript.

firefox3_files

Como podemos ver en Firebug, vemos que los elementos <input /> incorporan una propiedad DOM extra llamada files, que se compone de un array de elementos ordenados que hacen referencia a los ficheros subidos mediante ese elemento.

Esta propiedad, dispone de 3 métodos con las que podremos hacer uso de los elementos que subamos:

  • Atributos : fileSize y fileName
  • Métodos: getAsDataURL, getAsBinary y getAsText

Ejemplo de uso

function writeText() {
    var data = $('text').files.item(0).getAsBinary();
    $('result').update(data);
    $('textsize').update($('text').files.item(0).fileSize);
}
function writeImage() {
  var data = $('image').files.item(0).getAsDataURL();
  $('imageresult').src = 'data:' + data;
  $('imagesize').update($('image').files.item(0).fileSize);
}

Web Development Helper monitoriza ajax en tu Internet Explorer

25 May

+ 4

Gracias a edusanver descubro Web Development Helper es un plugin para Internet Explorer que nos permite, entre otras cosas, monitorizar las peticiones Ajax como si de Firebug en Firefox se tratara.

web_development_helper

Características

Entre las características más interesantes de este plugin se encuetran:

  • Inspector DOM de todos los elementos.
  • Capturas de imagenes de la página en la que estás.
  • Log de las peticiones HTTP (o HTTPS) solicitadas por el navegador o peticiones Ajax.
  • Ver las peticiones y respuestas en detalle.
  • Habilidad de filtrar por tipos de URL’s en los logs.
  • Traza de errores en detalle de las peticiones Javascript.
  • Consola con posibilidad de interacción Javascript usando (window.debugService).

Requerimientos

Descargar

Descargar

XDomainRequest() y como Microsoft hace lo que le da la gana

9 Mar

+ 2

Uno de los problemas con los que nos encontramos al usar Ajax en nuestras aplicaciones es que nos es imposible acceder, mediante javascript, a contenidos de otro servidor usando el el objeto XMLHTTPRequest(), debiendo recurrir a alternativas algo “sucias”, por ello la W3C decidió dotar a este objeto la posibilidad de trabajar en cross-domain, osea entre diferentes dominios. Esto facilitaría, por ejemplo la lectura de feeds, o cualquier tipo de contenido servido por páginas externas a nuestro dominio.

La aparición del primer borrador por parte de la W3C, hizo que los principales navegadores centraran su atención en esta nueva funcionalidad y se pusieran manos a la obra para dotar a sus navegadores de tan esperada y necesaria funcionalidad.

Con la aparición de un navegador que dije que no volvería a nombrar proximamente, apareció otra vez el dilema. XDomainRequest() ha sido el desencadenante, al alejarse del estandar ofrecido por la W3C.

Según la página del propio Microsoft, el uso de este nuevo objeto sería así:

// 1. Creamos el objeto XDR
xdr = new XDomainRequest();

// 2. Abrimos la conexión con el servidor usando el método POST
xdr.open("POST", "http://www.contoso.com/xdr.txt");

// 3. Enviamos información al servidor
xdr.send("data to be processed");

Como podemos ver, esto se parece a la actual forma de usar el objeto XMLHttpRequest() con la diferencia del nombre del objeto y de que la url a la que solicitamos la información se trata de una URL absoluta en lugar de una relativa.

Algo similar a lo propuesto por la W3C, que era extender al objeto XMLHttpRequest() con la capacidad de acceder a servidores remotos sin necesidad de modificar el código existente.

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.anieto2k.com/.../datos.php", true);
xhr.onreadystatechange = function(){
  if ( xhr.readyState == 4 ) {
    if ( xhr.status == 200 ) {
      document.body.innerHTML = "Respuesta: " + xhr.responseText;
    } else {
      document.body.innerHTML = "ERROR";
    }
  }
};
xhr.send(null);


Como podemos ver la diferencia nos hace recordar el odiado ActiveX() y las condiciones tan feas que hemos de hacer para hacer compatibles nuestros navegadores. ¿Ahora con la nueva versión tendremos que añadir una línea más?

var ajax =  function() {
  if (windows.XDomainRequest) { //IE8
	return new XDomainRequest();
  } else if (window.XMLHttpRequest) { //FF, Opera, IE7
    	return new XMLHttpRequest();
  } else if (window.ActiveXObject) { //IE6
  	return new ActiveXObject('Microsoft.XMLHTTP')
  } else { //No Ajax Compatibles
    	alert("No hay ajax");
   	return null;
  }
}

¿Nos encontramos con un nuevo ActiveX() (versión exclusiva para Internet Explorer 6.0) o será el nuevo innerHTML (Aceptado como parte del estandar tras ser una invención de Microsoft)?

XMLHttpRequest entre servidores con Firefox 3

10 Ene

+ 2

Hace un mes vimos Ajax Cross Domain Script, un script que nos permite realizar una conexión entre servidores mediante Ajax, resolviendo una limitación del objeto XMLHttpRequest().

Hoy John Resig, anuncia que Firefox 3 integrará siguiente versión evolutiva del objeto XMLHttpRequest(), permitiendo realizar peticiones entre servidores de forma directa y nativa

Modo de uso

Para asegurar una cierta seguridad, intervendrán varios factores que harán posible que podamos personalizar nuestra propia lista de sitios permitidos o denegados.

Para ello deberemos hacer uso de la cabecera Access-Control, que forma parte del borrador Access Control for Cross-Site. Permitiendo o denegando el acceso al servidor.

Cabeceras Acces-Control 

 Las cabeceras Acces-Control, podrán ser usadas desde cualquier lenguaje de programación capaz de modificar las cabeceras salientes del servidor. Veamos unos ejemplos:

Ejemplo

//PHP
<?php header('Access-Control: allow <*>'); ?> //Permitimos todos
<?php header('Access-Control: deny <*>');?>  //Denegamos todos
<?php header('Access-Control: allow <mozilla.org>');?> //Permitimos solo mozilla.org
<?php header('Access-Control: allow <mozilla.org> exclude <developer.mozilla.org>');?> //Permitimos mozilla.org y denegamos developer.mozilla.org
<?php header('Access-Control: allow <developer.mozilla.org:80> method GET, POST');?> //Permitimos developer.mozilla.org para el puerto 80 en los métodos GET y POST

//XML
<?access-control allow="*"?> //Permitimos todos
<?access-control deny="*"?> //Denegamos todos
<?access-control allow="mozilla.org"?> //Permitimos solo mozilla.org
<?access-control allow="mozilla.org" exclude="developer.mozilla.org"?> //Permitimos mozilla.org y denegamos developer.mozilla.org
<?access-control allow="developer.mozilla.org" method="GET POST"?> //Permitimos developer.mozilla.org para el puerto 80 en los métodos GET y POST

Pese a que el borrador informa que no es posible usar variables GET entre servidores, Firefox 3 parece que si lo hará.  

Javascript

Gracias a una implementación limpia, las aplicaciones Ajax no necesitarán ser modificadas ya que el uso será exactamente igual del que estamos haciendo uso ahora. Simplemente que la URL de nuestras peticiones pueden comenzar por HTTP :D

La mejor forma de usar las llamadas asincronas

12 Dic

+ 2

Con este título la gente de IBM nos muestra un artículo bastante interesante en el que vemos una forma muy interesante de hacer nuestras llamadas asincronas mediante javascript (Ajax), principalmente se trata de una función que como veremos más adelante inteta cubrir todos los flancos que pueden hacer fallar la experiencia asincrona.

Función propuesta completa

function getResource(uri, data_callback, error_callback, timeout) {
    var tryAgain = function () {
      getResource(uri, data_callback, error_callback, timeout);
    }
    var r = new XMLHttpRequest();
    var timer = setTimeout(
        function() {
            r.abort();
            r.onreadystatechange = null;
            setTimeout(tryAgain, timeout);
        },
        timeout);
    r.open("GET", uri, true);
    r.onreadystatechange = function() {
        if (r.readyState != 4) {
            return;
        }
        clearTimeout(timer);  // readyState==4, borramos timer
        if (r.status==200) {  // "OK status"
              data_callback(r.responseText);
        }
        else if (r.status==304) {
            // "Not Modified": No modificamos la salida
        }
        else if (r.status >= 400 && r.status < 500) {
            // Posible error, posible URI erronea
            error_callback(r)
        }
        else if (r.status >= 500 && r.status < 600) {
            // Server error, volvemos a lanzar con un poco de demora
            setTimeout(tryAgain, timeout);
        }
        else {
            error_callback(r);
        }
    }
    r.send(null);
    return r;
}

Función detallada

Empezando de arriba a abajo, tenemos la variable tryAgain, que no es más que la definición de una función que hace la misma llamada que hemos hecho inicialmente. Esta variable será usada para lanzar la función en caso de necesitar relanzarla por algún motivo.

var tryAgain = function () {
     getResource(uri, data_callback, error_callback, timeout);
   }

Sobre la variable r, recae la responsabilidad de albergar el objeto XMLHttpRequest() que hará posible el asincronismo. Aunque yo propongo algo más completo para asegurarnos que IE6 no se quede fuera de juego.

var r = new XMLHttpRequest();
//Más completo
var r = (XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');

Ya con el objeto principal cargado, declaramos la variable timer, que al igual que tryAgain solo será llamada en el caso en se requiera. Esta función se encargará abortar la transacción asíncrona al cubrir el tiempo timeout dado.

var timer = setTimeout(
        function() {
            r.abort();
            r.onreadystatechange = null;
            setTimeout(tryAgain, timeout);
        },
        timeout);

Una vez preparado el camino con las variables necesarias para el funcionamineto, solo nos queda hacer la llamada, en este caso por GET, y controlar los valores retornados para accionar una funcionalidad u otra.

Tratando la respuesta

Al igual que en el ejemplo anterior, la respuesta tambien debería ser tratada teniendo en cuenta un timeout que nos evitará demoras innecesarias. Para ello definiremos nuestra función usando una estructura similar a esta.

var other_data = null;
function processData(this_data) {
    var delay = 1000;     // Esperamos 1 segundo
    if (other_data == null) {
        setTimeout(function() { processData(this_data); }, delay);
        return;
    }
    // Tenemos this_data y other_data
    displayThisAndThat(this_data, other_data);
    // Reseteamos other_data, ya la hemos usado
    other_data = null;
}
// Ejemplo de uso
getResource(uri2,processData,errorData, 5000);

Ajax Cross Domain Script

10 Dic

+ 7

Una de las limitaciones que Ajax es el no poder acceder a datos de un dominio diferente al que estamos. Esto en la mayoría de casos nunca te lo plantearías, pero debería ser posible acceder a sitios externos, por ejemplo API’s, desde el navegador de nuestro cliente aunque sea un dominio diferente al propio.

Hasta ahora la solución era usar un script en tu local a modo de lector de la página externa y devolver el resultado, algo que no siempre podríamos llevar a cabo. Por eso nace Ajax Cross Domain, una aplicación que nos permite hacer esto sin tener que instalar nada en nuestro servidor,únicamente llamar al script que se encarga de obtener los datos y para procesarolos nos ofrece una mini API que nos permitirá trabajar con ellos igual que si fueran de nuestro dominio.

Ejemplo

<script type="text/javascript" src="http://www.ajax-cross-domain.com/cgi-bin/ACD/ACD.js?uri=(http://216.92.176.52/?name=john)"></script>
<script type="text/javascript"> alert(ACD.responseText);
</script> 

¿Como funciona?

schema.gif

Como vemos en la imagen, al llamar al script, este controla si se trata de una llamada a tu propio dominio o si es externo, en caso de ser externo gestionará la forma de generar un objeto ACD con los datos procedentes de la petición.

Loggea el movimiento del ratón de tus usuarios

19 Oct

+ 4

Via Ajaxian, descubro como loggear el movimiento del ratón de tus usuarios mediante javascript y ajax. Puede ser una forma muy útil de conocer que hacen los usuarios en tu página. [Demo]