Ver Mensaje Individual
  #1  
Antiguo 07-01-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Reputación: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Ajax.class.js - Sencilla forma de hacer peticiones HTTP en segundo plano

Hola,

Escribí hace tiempo una sencilla clase en JavaScript para tratar con el objeto famoso XmlHttpRequest. Es unan sencilla clase porque no pretende ir muy allá, y, sin embargo, llevo un par de días añadiendo y quitando alguna que otra cosa.

El caso es que he pensado que acaso vosotros podéis decir algo al respecto: que sobra algo, que podría añadírsele tal o cual cosa, en fin, lo que gustéis. A continuación copio el código de la clase JavaScript.

El código HTML, CSS, JS y su "funcionamiento" puede verse aquí: http://dec.clubdelphi.com/ajax.class.js/

Puede descargarse todo el código fuente (incluído PHP) desde aquí: http://dec.clubdelphi.com/ajax.class...x.class.js.zip

Código PHP:
/**
 * Sencilla clase para manejarse con el objeto XmlHttpRequest
 * de modo que podamos hacer peticiones HTTP Get y HTTP Post.
 * 
 * @author dec
 */
var Ajax =
{
    
/**
     * Realiza una simple petición HTTP Get. Este método permite determinar
     * una función que se ejecutará según progrese la petición HTTP, y otra
     * función que se ejecutará cuando dicha petición HTTP se complete.
     * 
     * @param {string} url
     * @param {string} destino
     * @param {function} funcProgreso
     * @param {function} funcFinal
     */
  
Get:function(url,destino,funcProgreso,funcFinal){                
      return 
this.HttpRequest(url,destino,'','get',funcProgreso,funcFinal);    
    },

  
/**
   * Igual que "Get", salvo que la petición es HTTP Post.
   * 
     * @param {string} url
     * @param {string} destino
     * @param {function} funcProgreso
     * @param {function} funcFinal
     */
    
Post:function(url,destino,funcProgreso,funcFinal){                
      return 
this.HttpRequest(url,destino,'','post',funcProgreso,funcFinal);    
    },
    
    
/**
     * Similar al método "Get" salvo que en este caso ha de incluirse la query
     * que ha de llevar consigo la petición HTTP Get.
     * 
     * @param {string} url
     * @param {string} destino
     * @param {string} query
     * @param {function} funcProgreso
     * @param {function} funcFinal
     */
    
GetQuery:function(url,destino,query,funcProgreso,funcFinal){                
      return 
this.HttpRequest(url,destino,query,'get',funcProgreso,funcFinal);    
    },

    
/**
     * Igual que "GetQuery", salvo que la petición es HTTP Post.
     * 
     * @param {string} url
     * @param {string} destino
     * @param {string} query
     * @param {function} funcProgreso
     * @param {function} funcFinal
     */
    
PostQuery:function(url,destino,query,funcProgreso,funcFinal){                
      return 
this.HttpRequest(url,destino,query,'post',funcProgreso,funcFinal);    
    },

  
/**
   * Este método se encarga de la creación del objeto XmlHttpRequest y de asig-
   * nar a este las propiedades oportunas y de llamar a los métodos correspon-
   * dientes. Podría considerarse este método como privado, en el sentido de
   * que para usar esta clase bastan los métodos anteriores.
   * 
   * @param {string} url
   * @param {string} idDestino
   * @param {string} query
   * @param {string} metodo
   * @param {function} funcProgreso
   * @param {function} funcFinal
   */
  
HttpRequest:function(url,idDestino,query,metodo,funcProgreso,funcFinal){
    
// Instanciamos un objeto XmlHttpRequest         
    
var request this.XmlHttp();
        
    
// Nos hacemos con un enlace al elemento de destino
    
var destino document.getElementById(idDestino);        
        
    
/* Comprobamos que contamos con un objeto XmlHttpRequest
     * y que también está disponible el elemento de destino.
     * De no ser así no hay para qué seguir...
     */
    
if (!request || !destino){ return false; }
    
    
/* Vamos a preparar la función "al vuelo" que se va a encargar
     * de "escuchar" el evento "onreadystatechange" del objeto Xml-
     * HttpRequest.
     */ 
        
request.onreadystatechange = function(){
            
            
/* "readyState = 1" con la tarea en progreso.
             * Si hay alguna función para tal fin la llamamos.
             */
            
if(request.readyState == 1){
              if(
funcProgreso) { funcProgreso(destino); }
          }
            
      
/* La propiedad "readyState" del objeto "XmlHttpRequest" nos
       * indica que la petición HTTP terminó de realizarse...
       */
      
if(request.readyState == 4){
                
                
/* Si contamos con una función para que esté atenta al final
                 * de la tarea la llamamos a continuación.
                 */
                
if(funcFinal) { funcFinal(request.status,destino); }
                
        
/* En este caso queda comprobar que el código de la propiedad
         * "status" del objeto XmlHttpRequest valga 200. Se trata del
         * código de resultado HTTP que indica que la petición se resol-
         * vió correctamente, esto es, que tenemos el recurso solicitado
         */
        
if (request.status == 200)
          
/* En este caso no nos quedaría sino escribir la respuesta de
           * la petición en el elemento HTML de destino. Ni más ni menos.
           */
          
destino.innerHTML request.responseText;
      }
    }        
    
// Comprobamos que el método de la petición HTTP es "get"
    
if(metodo.toLowerCase() === 'get') {    
      
/* Si es así preparamos la petición HTTP utilizando el método
       * "open" del objeto XmlHttpRequest. Nótese cómo indicamos primero
       * el método a utilizar, a continuación proporcionamos la URL junto
       * con la "query", y por último indicamos que la petición se realize
       * en segundo plano, es decir asíncronamente.
       */
      
request.open(metodourl+"?"+querytrue);
      
// Preparada la petición, no queda sino enviarla.
      
request.send(null);
    } 
    
// Si el método de la petición HTTP no es "get" ha de ser "post"
    
else if(metodo.toLowerCase() === 'post') {
      
/* Y en este caso los parámetros para el método "open" son los mismos,
       * excepto en lo que toca a la "query", que no va junto a la URL ahora
       */ 
      
request.open(metodourltrue);
      
/* Añadimos la cabecera HTTP que hará que la petición sea tratada de la
       * forma que nos interesa, esto es vía POST. Nótese que si el método es
       * Get no hace falta añadir cabecera alguna.
       */
      
request.setRequestHeader('Content-Type',
       
'application/x-www-form-urlencoded');
      
/* Y por último enviamos realmente la petición con el mismo método
       * "send" de antes, sólo que ahora pasamos como parámetro la "query".
       */
      
request.send(query);
    }
    return 
true;
  },

  
/**
   * Este método es privado. Lo usamos en el método anterior "HttpRequest"
   * para lograr una instancia del objeto XmlHttpRequest. Como puede verse
   * lo "intentamos" de varias formas, teniendo en cuenta que distintos na-
   * vegadores exponen dicho objeto de distinto modo.
   * 
   * Cuando uno de los intentos frutúe no hará falta continuar, y, en caso
   * de que los tres intentos fallen este método se limita a devolver "null".
   */
  
XmlHttp:function(){
    try { return new 
XMLHttpRequest();                   } catch(e) {}
    try { return new 
ActiveXObject('Msxml2.XMLHTTP');    } catch(e) {}
    try { return new 
ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
    return 
null;
  }
}; 
Ya sabéis que aunque el código fuente anterior es JavaScript aunque se incluya entre etiquetas PHP para resaltarlo mejor.

Ojo que la clase no pretende ser completa, en el sentido de aprovechar al máximo el objeto XmlHttpRequest. Se trata, al contrario, de conseguir una forma muy sencilla de usar dicho objeto, aunque nos perdamos algunas de sus características.

Una cosa que puedo decir ya que le falta a la clase Ajax (je) es que no "avisa" del progreso de la tarea. Es decir, que no sé muy bien cómo enfocar este tema. Por otro lado está el caso de que la tarea (petición HTTP) falle. Tampoco ante esto me parece muy claro el comportamiento de la clase.

Pero, en fin. Yo lo dejo ahí que parecía que no podía dejar de hacerlo. No os veáis obligados a comentar ni a decir ni a dejar de decir. Al fin y al cabo es un poco de código el que he puesto en este Hilo, por si le puede servir a alguien, por si alguien quiere comentar algo, pero, no pretendo ir mucho más allá.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 10-01-2007 a las 17:12:34.
Responder Con Cita