Programación Web en cliente

El formato JSON

Para el intercambio de información entre cliente y servidor a través de AJAX, además de usar el lenguaje XML usaremos JSON. La definición formal de JSON que encontramos es la siguiente:

JSON, acrónimo de JavaScript Object Notation, es un formato ligero para el intercambio de datos. JSON es un subconjunto de la notación literal de objetos de JavaScript que no requiere el uso de XML.(wikipedia).

Más adelante vamos a ver en que consiste la notación literal en Javascript, pero ya adelantamos que el uso de JSON en Javascript nos va a permitir una mayor integración con nuestros scripts, puediento tratar la información directamente (recordar que en XML debemos recorrer el documento e ir recogiendo la información para pasarlas a nuestras variables en Javascript).

Otra de las ventajas que encontramos con JSON respecto a XML es que el código resultante es bastante mas liviano. Para guardar la misma información utilizando JSON en vez de XML se reduce el tamaño ya que no produce redundancia de datos y esto repercute en una mayor velocidad a la hora de transmitir la información. En los siguientes fragmentos de código se puede ver la misma información en JSON y XML.

Literales de matriz y objeto en Javascript

Como se encontramos en la definición de JSON, este es un subconjunto de la notación literal de objetos de Javascript. Para entender esto, vamos ver varios ejemplos de notación literal:

En este primer ejemplo, podemos ver como para definir un vector en Javascript usamos la notación literal de matriz (un vector no es más que un caso particular de matriz):

//Literal de matriz
var literal = ["uno", "dos", "tres"];
alert(literal[1]); // devuelve dos

Si queremos definir los valores de un objeto usaremos la siguiente sintaxis:

//Literal de objeto
var oLibro = {
   "isbn" : "0000000001",
   "titulo": "Don Quijote",
   "autor" : "Cervantes"
}
alert(oLibro.titulo); // devuelve Cervantes

Por último podemos combinar la notación de matriz y objeto para tener un literal mixto:

//Literal mixto
var oLibroVector = [{
   "isbn" : "0000000001",
   "titulo": "Don Quijote",
   "autor" : "Cervantes"
},{
   "isbn" : "0000000000",
   "titulo": "La Biblia",
   "autor" : "varios"
}];
alert(oLibroVector[1].autor); //devuelve varios

Usando JSON en nuestros scripts

Conociendo como definir los literales de matriz y objeto en Javascript, usar la sintaxis de JSON no es mas que la adopción de estos. JSON solo representa datos, y estos son enviados y recibidos como cadenas de texto que guardan la sintaxis de los literales de matriz y objeto. Por ejemplo para enviar o recibir información sobre un libro usaremos esta cadena de texto:

{"isbn" : "0000000001", "titulo": "Don Quijote", "autor" : "Cervantes"}

Podemos almacenar el texto que nos llega desde el servidor (o desde el cliente en PHP) en una variable (pj: stringJSON), pero hasta que no evaluemos el código no podremos tratarlo como objeto. La idea es comunicarse mediante texto plano pero usando la sintaxis de los literales de matriz y objeto, para después poder evaluarlo y tener así vectores, matrices y objetos. Recordar que evaluar un string es como haber escrito el código que contiene ese string. En Javascript usaremos la función eval() para este cometido. A continuación mostramos un ejemplo de como almacenamos una cadena de texto donde escribimos en notación literal de objeto un libro, para posteriormente evaluar y poder utilizarlo:

<html>
   <head>
      <script>
         var sJSON = '[{"isbn":"670894788",
            "titulo":"Anna Karenina",
            "autor":"Leo Tolstoy"}]';
         //decodificamos JSON y creamos la variable oLibro
         var oLibro = eval(sJSON); 
         alert(oLibro[0].titulo);
      </script>
   </head>
   <body> 
   </body>
</html>

JSON en el servidor

Teniendo en cuenta que AJAX se utiliza para la comunicación entre cliente y servidor, no tendría sentido utilizar JSON si no estuviera soportado en el lenguaje Servidor que utilicemos. En este curso vamos a estudiar una solución implementada en PHP, JSON-PHP. JSON-PHP facilita la codificación y decodificación de código JSON en PHP.

Las versiones más modernas de PHP (> PHP 5.3) ya tienen instalada funciones que permiten la codificación y decodificación de cadenas JSON. Esta funciones son:

  • string json_encode ($var) // donde $var puede ser cualquier tipo (vector, objeto etc...), se devuelve una cadena de texto en formato JSON
  • json_decode ($string) // se convierte una cadena de texto en formato JSON a un vector, objeto, etc.

Si nuestra versión de PHP es menor de la 5.3. podemos también utilizar JSON. Una opción es mediante PHP-PEAR (en este documento no se explicará PHP-PEAR, pero puede encontrarse información en la web oficial: http://pear.php.net/ ) bajar la extensión PEAR-JSON e instalarla. También existen librerías de terceros que podemos descargarnos, como por ejemplo la del proyecto JSON-PHP (http://mike.teczno.com/json.html).

A continuación mostramos un ejemplo de código de como desde PHP declaramos una clase libro, instanciamos un objeto del mismo (recogiendo información de la base de datos) y lo convertimos en un string JSON para que pueda ser enviado mediante AJAX:

<?php
class Libro{
   public $isbn;
   public $titulo;
   public $autor;
   function Libro($isbn,$titulo,$autor){
      $this->isbn = $isbn;
      $this->titulo = $titulo;
      $this->autor = $autor;
   }
}

$libros = array();
$libros[0] = new Libro("0000000000","La bliblia","varios");
$libros[1] = new Libro("0000000001","Don Quijote de la Mancha","Cervantes");
$libros[2] = new Libro("0000000002","Yo, Robot","Isaac Asimov");

$sJSON = json_encode($libros);
print($sJSON);
?>

Ejemplo de comunicación AJAX con JSON

Como resumen de todo lo explicado en la parte de JSON, vamos a mostrar un código de ejemplo con una comunicación AJAX. El ejemplo consta de 2 partes:

Por un lado tenemos la parte HTML/Javascript donde crearemos una web en la que incluiremos un div con identificador “datosLibros”, dentro de este div mostraremos la información que nos llegue del servidor. Para ello llamaremos en el onLoad del body (recordar que es cuando el cuerpo de la web termina de cargarse) a la función “enviar()”. Esta función hará un llamada AJAX de tipo GET y esperará un string JSON como parametro de vuelta en la función “leerDatos()” (recordar que leerDatos es el callback que se ejecutará cuando se nos haya devuelto la llamada AJAX). Una vez el string JSON haya llegado a la función “leerDatos()” este realizará un bucle para crear de forma dinámica una tabla en HTML donde se mostrará la información de los libros.

En la segunda parte del ejemplo, mostramos el código PHP. Declararemos la clase libro, haremos una consulta de base de datos e instanciaremos tantos objetos libro como encontremos. Estos serán codificados en JSON y devueltos al cliente (que los leerá en su función callBack de Javascript -en este caso, “leerDatos()”-)

### HTML Y JS ###

<html>
   <head>
      <script type="text/JavaScript" src="jquery.js"></script>
      <script>
         function enviar()
         {
            $.getJSON("jsonRequestBd.php",null,leerDatos);
         }
         function leerDatos(originalRequest)
         {
            html = "";
            oLibros = originalRequest;
            html += "<table><tr><td width='100'>ISBN</td>”;
            html += “<td width='150'>TITULO</td>
               <td width='150'>AUTOR</td></tr>";
            for(var i=0; i < oLibros.length; i++)
            {
               html += "<tr>";
               html+="<td>"+oLibros[i].isbn+"</td>";
               html+="<td>"+oLibros[i].titulo+"</td>";
               html+="<td>"+oLibros[i].autor+"</td>";
               html += "</tr>"
            }
            html += "</table>";   

            $('#datosLibros').html(html);   
         }
      </script>
   </head>
   <body onLoad="enviar()">
      <div id="datosLibros">
         <table width="400">
            <tr><td align="center"><img src="indicator.gif"></td></tr>
         </table>
      </div>
   </body>
</html>
### PHP ###

<?php

class Libro{
   public $isbn;
   public $titulo;
   public $autor;
   function Libro($isbn,$titulo,$autor){
      $this->isbn = $isbn;
      $this->titulo = $titulo;
      $this->autor = $autor;
   }
}

$rootBdUser = "root";
$rootBdPass = "";
$nombreBd = "uazon_des";

$conn = mysql_connect("localhost",$rootBdUser,$rootBdPass);
mysql_select_db($nombreBd,$conn);

$sql = "Select l.isbn,l.titulo, a.nombre 
   from libros l, autores a, libros_autores la 
   where ((l.id = la.fk_libros) and (la.fk_autores = a.id))";
$Rset = mysql_query($sql);

$contador = 0;  
while($row = mysql_fetch_array($Rset))
{
   $isbn = $row[0];
   $titulo = $row[1];
   $autor = $row[2];
   $libros[$contador] = new Libro($isbn,$titulo,$autor);
   $contador++;
}

mysql_free_result($Rset);

$sJSON = json_encode($libros);
print($sJSON);

?>