Este capítulo tiene como finalidad introducir los componentes y tecnologías
intervinientes en la web en el lado del cliente.
Se comienza con un breve análisis de un navegador web y el protocolo de transferencia
de hipertexto HTTP. Luego, se describe HTML y CSS y se finaliza el apartado con
una descripción un poco más detallada sobre JavaScript.
Por último se analiza el plug-in Google Gears, que añade componentes esenciales
para el trabajo desconectado de una aplicación web a un navegador.
Web Dinámica desde la Perspectiva del Cliente
Desde la perspectiva del usuario, la web consiste en una gran cantidad de
documentos interconectados a nivel mundial, llamados páginas web, a los cuales
se accede mediante un navegador.
Cada uno de estos documentos está escrito en un lenguaje de marcado (o etiquetas), típicamente
HTML, que utiliza a su vez dos lenguajes:
- CSS para definir el estilo de las páginas de manera consistente.
- Javascript para definir la interacción en la página (JavaScript es el único
mecanismo estándar para brindar dinamismo a una página web).
JavaScript [WikiJavascript09] ha tenido durante mucho tiempo la reputación de ser un lenguaje
inadecuado para el desarrollo serio. Una de las razones fue que, a pesar
de los estándares impuestos por la European Computer Manufacturers Association (ECMA) [ECMAScript09],
los desarrolladores de navegadores realizaron sus propias variantes
del lenguaje, como Microsoft en la implementación de JScript [MSFTJScript09] para su navegador
Internet Explorer (IE). Estos problemas relegaron a JavaScript a tareas prescindibles, como validación de formularios
en el cliente y efectos visuales simples.
Un problema similar ocurrió con Document Object Model (DOM), el mecanismo por el cual se interactúa con el
documento y el navegador, estandarizado por la World Wide Web Consortium (W3C) . Sus versiones fueron
nombradas como nivel DOM, existiendo nivel 0, 1, 2 y 3.
No todos los navegadores implementaron por completo los niveles, dando lugar a confusión e incompatibilidades.
A partir de la aparición de AJAX , una técnica de desarrollo web para crear
aplicaciones interactivas, los desarrolladores diseñaron librerías de JavaScript
que presentaron una API uniforme que salvaba las incompatibilidades existentes.
Con la popularización de estas librerías, también lo hicieron las herramientas de
depuración sofisticadas como Firebug [Firebug09], lo que permitió realizar aplicaciones
más complejas y compatibles con la gran mayoría de los navegadores del mercado.
Google lanzó, en 2007, un plugin para los navegadores populares,
llamado Google Gears, que agrega tres componentes:
Web Server
Un servidor de archivos que se ejecuta en el cliente.
DataBase
Una base de datos transaccional.
Worker Pool
Un mecanismo para la ejecución de JavaScript como procesos.
Estructura de un Navegador
Navegador Web
Es un software que presenta documentos de hipertexto al usuario.
Los lenguajes de codificación de hipertexto más populares son HTML y XHTML.
Un navegador no sólo interpreta los documentos de hipertexto, sino
que también puede mostrar otros tipos de contenidos, como imágenes
(JPEG, GIF, PNG, etc.), sonido (WAV, MP3, OGG), vídeo (MPEG, H264, RM, MOV),
así como elementos interactivos (como el caso de Macromedia Flash,
applets Java o controles ActiveX en la plataforma Windows).
Debido a la cantidad de recursos que debe manejar un navegador,
el servidor web agrega a cada respuesta al cliente una cabecera donde le indica
el tipo de recurso que está entregando. Esta especificación se realiza con el
estándar MIME.
Un navegador web acepta como entrada del usuario una URL.
Una vez validada, éste descarga el recurso apuntado mediante el protocolo HTTP.
Una URL tiene la siguiente estructura:
Los componentes de una URL son:
Esquema
Especifica el mecanismo de comunicación. Generalmente HTTP y HTTPS .
Anfitrión
Especifica el nombre de dominio del servidor en Internet, por ejemplo:
google.com, nasa.gov, wikipedia.com, etc.
Se popularizó la utilización del subdominio “www” para identificar al
anfitrión que ejecuta el servidor web, dando lugar a direcciones del tipo
www.google.com, www.nasa.gov, etc.
El puerto es un parámetro de conexión TCP, y suele ser omitido debido
a que el esquema suele determinarlo, siendo 80 para HTTP y 443 para HTTPS.
Recurso
Especifica dentro del servidor, la ruta para acceder al recurso.
Query
El parámetro query tiene sentido cuando el recurso apuntado por la ruta
no se trata de una página estática y sirve para el pasaje de parámetros.
El programa que genera el recurso puede recibir como argumentos estos
parámetros, por ejemplo, cuando se ingresa la palabra foo en el buscador
Google, la URL que provee el resultado de la búsqueda es:
http://www.google.com/search?**q=foo**
Enlace
Dentro de un documento de hipertexto pueden existir enlaces internos.
Gracias a este parámetro se puede enlazar a una sección específica de un documento,
permitiendo al navegador ubicarse visualmente.
Un navegador generalmente accede a documentos ubicados en la web mediante el
protocolo HTTP. Sin embargo, es posible acceder a documentos locales, donde el
esquema suele ser file y el anfitrión se encuentra ausente, por ejemplo:
file:///home/nacho/paginas/pepe.html
HTTP
HTTP es el protocolo de transferencia de hipertexto.
Para acceder al recurso archivos/curso_javascript.html en el servidor
students.unp.edu.ar, de la url http://students.unp.edu.ar/archivos/curso_javascript.html,
el navegador conforma la siguiente consulta:
GET /archivos/curso_javascript.html HTTP/1.1
Host: students.unp.edu.ar
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-ar,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Cookie: user_id=G7NVG5YY51I9DZAIJDEDQIXYQSRF0CTL
Esto se conoce como una consulta HTTP o HTTP Request.
En la primer línea se especifica el método HTTP y el nombre del recurso, junto con la
versión del protocolo que soporta el navegador (o cliente):
GET /archivos/curso_javascript.html HTTP/1.1
La segunda línea especifica el host al cual se accede. Como un servidor web puede estar
publicado en varios dominios, mediante esta línea se puede discriminar a cuál se
intenta acceder:
Host: students.unp.edu.ar
El siguiente componente del request es la línea que identifica al cliente, en
este caso el navegador informa que se trata de Mozilla versión 5:
Una vez que el servidor web ha localizado y accedido al recurso, procede a enviar
la respuesta, que generalmente es una página codificada en HTML.
HTML
HTML es un lenguaje de marcado que tiene como objetivo describir un documento
de hipertexto.
Un documento HTML se conforma por una serie de tags o etiquetas, las que tienen
el siguiente formato:
Un documento HTML está delimitado por las etiquetas html y contiene una
cabecera delimitada por head y un cuerpo, delimitado por body. Por ejemplo:
<html>
<head>
<title>Mi pagina</title>
</head>
<body>
<h1>Título principal</h1> <!-- comentario -->
<p>Párrafo</p>
</body>
</html>
También suele contener enlaces a recursos entendibles para el navegador,
como a las hojas de estilos o código JavaScript.
La inclusión de una hoja de estilo se realiza mediante la etiqueta link, de la
siguiente manera:
<link type="text/css" rel="stylesheet" href="hoja_de_estilos.css">
Se puede, además, embeber en la página el estilo CSS, como en:
<style type="text/css">
BODY {
font-family: "Verdana";
font-size: 12pt;
padding: 2px 2px 3px 2px;
}
</style>
Al incrustarse el estilo en una página en particular, éste sólo tiene
validez para ese recurso.
Mediante la etiqueta script se incluye código JavaScript, aunque es
posible utilizar otros lenguajes, como VBScript en IE. Por ejemplo:
<script type="text/javscript" src="/medios/js/mi_codigo.js"></script>
De manera similar a lo que ocurre con el estilo, el código JavaScript se
puede embeber en el código HTML de varias formas [StephenChapmanJS2009], entre
ellas:
<script type="text/javascript">
var x = 2;
var y = 4;
</script>
CSS
CSS es un lenguaje utilizado para definir el estilo de las páginas.
Una hoja de estilo en cascada o StyleSheet determina cómo se va a mostrar un documento
en pantalla, cómo se va a imprimir o, inclusive, cómo se realiza la pronunciación a través de un
dispositivo de lectura [W3cCSS2009].
El objetivo de CSS es separar el contenido de la presentación de un documento
HTML o XML. Una hoja de estilos puede ser enlazada desde varias páginas, permitiendo
mantener coherencia y consistencia en todo el sitio.
JavaScript
JavaScript es un lenguaje de programación interpretado creado originalmente por
Brendan Eich, para la empresa Netscape, con el nombre de Mocha. Surgió
a principios de 1996, como un lenguaje de scripting para la web y enfocado en la
interacción directa con el usuario.
Tiene una sintaxis semejante a la de Java y C, pero JavaScript dista mucho de
ser Java y debe su nombre más a cuestiones de marketing que a principios de diseño.
De hecho, fue influenciado por lenguajes como Self, Scheme, Perl, e incluso en
versiones modernas, por Python.
Si bien JavaScript es un lenguaje orientado a objetos, carece de clases
y ocultamiento de información. Existen varias técnicas para lograr encapsulamiento,
abstracción, herencia y polimorfismo. Entre las más utilizadas se encuentran el
arreglo asociativo, el uso de prototipos y las clausuras.
Arreglo Asociativo (Object)
Este tipo de dato representa una lista de asociaciones clave-valor, donde
la clave y el valor pueden ser de cualquier tipo arbitrario.
Además el operador de indexación en el arreglo [] (corchetes) responde de la misma
manera que el operador . (punto). Por ejemplo:
// Definción de un arreglo asociativo
>>> var x = {nombre: "Eduardo", apellido: "Expósito", edad: 47, factor: 2.5}
>>> x['nombre']
"Eduardo"
>>> x.nombre
"Eduardo"
El arreglo asociativo tiene la particularidad de que en la invocación
de las funciones miembro (es decir, contenidas como valor de alguna asociación),
la palabra this apunta a la instancia de arreglo. De esta manera se obtiene
un comportamiento similar a el tipo struct de C++, como se ve en el siguiente
ejemplo:
>>> var obj = {
metodo: function () {
print(this.x);
}
x: 3
}
>>> obj.metodo();
3
Esta técnica se utiliza en combinación con las clausuras en las librerías
de JavaScript, como Prototype [ProtypeOrgSrc09], para lograr encapsulamiento.
Prototipos
Un prototipo es el equivalente a una clase en los lenguajes como Java o C++.
Consiste en la definición de la función que es llamada anteponiendo la
palabra reservada new. Durante la llamada, this apunta a la instancia
que está siendo creada. El código de la función se comporta como un constructor
de instancias. Por ejemplo:
>>> var Clase = function () {
this.metodo = function () {
console.log( this.valor );
}
this.valor = 3;
}
>>> var instancia = new Clase();
>>> instancia.metodo();
-> 3
Sin embargo, la definición de métodos utilizando la sintaxis this.metodo = ...
realiza una nueva copia del método por cada instancia.
Para acceder a la estructura de la clase, se utiliza el atributo
prototype. Este atributo almacena la estructura de la clase y consiste
en un arreglo asociativo, como se ve en siguiente ejemplo:
>>> var Clase = function () {}
>>> Clase.prototype.metodo = function () {
console.log( this.valor );
}
>>> Clase.prototype.valor = 3;
>>> var instancia = new Clase();
>>> instancia.metodo();
-> 3
Esta técnica permite implementar herencia.
Clausuras
Una clausura es la utilización de funciones internas con referencias locales
que permanecen enlazadas aún cuando el contexto contenedor ha desaparecido [StuartLangridgeClosures09].
Mediante esta técnica se suele lograr encapsulamiento y ocultamiento de información.
Por ejemplo:
>>> function mostrar_saludo(nombre) {
var saludo = "Hola";
function saludar(){
print(saludo);
}
return saludar;
}
Son muy utilizadas para funciones relacionadas con temporizadores, manejadores de eventos
y respuestas asincrónicas.
DOM
DOM (Document Object Model ) es una API para documentos XML y HTML. Provee una representación en objetos de
la estructura del documento, que permite modificar tanto el contenido como la representación visual.
Su función esencial es conectar al navegador con un lenguaje de programación [MDCDOM09].
Cada fabricante de navegador web [WIKIDOM09] realizó en principio su propia implementación de DOM,
razón por la cual la W3C emitió una especificación,
en octubre de 1998, denominada DOM.Nivel 1
en la cual se consideraron las características y manipulación
de todos los elementos existentes en los archivos HTML y XML [W3CDomLevels09].
| [W3CDOM09] | World Wide Web Consortium, Document Object Model, último acceso octubre 2009,
http://www.w3.org/DOM/ |
En noviembre de 2000 se emitió la especificación del DOM.Nivel 2. En ésta
se incluyó la manipulación de eventos en el navegador,
la capacidad de interacción con CSS, y la manipulación de partes del texto en las páginas
web.
DOM.Nivel 3 se emitió en abril de 2004; utiliza DTD (Definición del Tipo de Documento)
y validación de documentos.
La siguiente figura muestra la jerarquía de objetos que provee DOM en el navegador
para controlar tanto la representación del documento como algunos elementos del
navegador:
DOM define una estructura jerárquica de objetos, donde window representa
la ventana o pestaña del navegador. window.history hace referencia
al historial de navegación. Por ejemplo, el siguiente código, retrocede una página
en el historial:
window.history.back();
// Pero como window es el ámbito global, se puede abreviar a
history.back();
El elemento document referencia al documento (X)HTML. Posee los atributos body
y head que representan los bloques homónimos en HTML,
una serie de métodos para recuperación de elementos
(document.getElementByID(), document.getElementsByTagName()), atajos
a los formularios y otros elementos (document.forms, document.anchors,
document.applets, etc.). También tiene la capacidad de crear elementos.
Toda la jerarquía que deriva de document es instancia del tipo HTMLElement,
el cual le confiere una API que permite gestionar el árbol jerárquico. Algunos
elementos de esta API son:
children // Lista de sólo lectura de nodos hijos
appendChild(el) // Agrega un elemento
parentNode // Apunta al elemento padre
Mediante esta API se pueden realizar tareas como atender eventos y modificación
de DOM, como se ve en el siguiente ejemplo:
<html>
<head>
<title>Pruebas de eventos</title>
<script>
window.onload = function () {
var link = window.document.getElementById('un_link'),
div = document.getElementById('cosa');
link.onclick = function (event) {
// Crear un elemento párrafo
var un_p = document.createElement('p'),
txt = prompt('Ingrese un texto');
un_p.innerHTML = txt;
div.appendChild(un_p);
}
}
</script>
</head>
<body>
<a id="un_link">Pulsar aquí</a>
<div id="cosa">
</div>
</body>
</html>
El código JavaScript de un documento se evalúa en el contexto del elemento window,
como espacio de nombres global. Es decir, que cualquier variable global pertenece a window.
Por ejemplo:
>>> window.x = 3;
>>> x
3
AJAX
AJAX (Asynchronous JavaScript And Xml) es una tecnología que surge tras la
necesidad de agilizar las interfaces de usuario basadas en la web.
Es utilizada para lograr RIAs basadas en en las capacidades nativas del
navegador (sin plugins de terceras partes ).
Consiste en
la capacidad del navegador de originar peticiones HTTP que no
inicien una carga del documento (segundo plano). Permite realizar interfaces web más interactivas,
debido a que las transferencias asincrónicas sólo recuperan del servidor
los elementos que requieran ser actualizados.
AJAX es una tecnología asincrónica en el sentido de que los datos adicionales se
requieren al servidor y se cargan en segundo plano sin interferir con la
visualización ni el comportamiento de la página.
JavaScript es el lenguaje en el que normalmente se efectúan las funciones
de llamada de AJAX, mientras que el acceso a los datos se realiza mediante el objeto
XMLHttpRequest. En cualquier caso, no es necesario que el contenido asíncrono
esté formateado en XML.
Estas peticiones se programan en JavaScript y, si bien
originalmente se pensó en XML como lenguaje de intercambio de datos, es posible
transferir cualquier tipo de archivo como código HTML, código JavaScript,
imágenes, hojas de estilos, JSON, etc.
Esta tecnología utiliza cuatro elementos [WIKIAJAX09]:
- XHTML (o HTML) y hojas de estilos en cascada (CSS) para el diseño que
acompaña a la información.
- DOM como método de control de la representación y el navegador por
parte de JavaScript.
- El objeto XMLHttpRequest para intercambiar datos de forma asíncrona con el
servidor web. En algunos frameworks y en algunas situaciones concretas, se usa
un objeto iframe en lugar del XMLHttpRequest para realizar dichos
intercambios.
- XML es el formato usado generalmente para la transferencia de datos
solicitados al servidor, aunque cualquier formato puede funcionar, incluyendo
HTML pre-formateado, texto plano, JSON y hasta EBML.
Funcionamiento
Se crea y configura un objeto XMLHttpRequest:
var req = new XmlHTTPRequest();
req.open('GET', 'http://host.com/uri');
// Configuración del callback del evento
req.onreadystatechange = function () {
// Al igual que como se vio en el comportamiento
// de un arreglo asociativo, this se refiere a la
// petición.
if (this.readyState == 4) {
if (this.status == 200) {
alert("Se completó la descarga asincrónica");
}
}
}
El objeto XMLHttpRequest realiza una llamada al servidor:
La petición se procesa en el servidor.
El servidor retorna un documento XML (o algún otro tipo) que contiene el resultado.
El objeto XMLHttpRequest llama a la función onreadystatechange y procesa el resultado.
Se actualiza la página mediante DOM.
AJAX presenta ciertas ventajas para realizar aplicaciones interactivas, como mayor
interactividad, reducción de latencia de las aplicaciones y uniformidad entre las
plataformas. Sin embargo presenta algunos detalles a tener en cuenta debido a que,
al no realizarse recargas del documento, la URL permanece estática; entre ellos
se pueden mencionar: complicaciones en la manipulación del botón Volver hacia Atrás
del navegador (que requiere a veces iframes), problemas para agregar favoritos
y dificultades para la impresión.
JSON
JSON [JSONOrg2009] (JavaScript Object Notation) es un estándar de codificación de datos,
inspirado en la sintaxis de objetos de JavaScript.
Sus objetivos son:
- Ser legible para los programadores.
- Ser fácil de interpretar para las computadoras (en principio debido a la cercanía con JavaScript).
Surge como alternativa a XML para el intercambio de datos en aplicaciones
web.
Los desarrolladores descubrieron que formateando los datos como una cadena
literal para ser luego interpretada por la sentencia eval() [JSONOrgJS09]
podían visualizar los datos que eran enviados al cliente en un formato legible,
de gran ayuda a la hora de realizar depuración.
La sentencia eval() es considerada peligrosa
[SimonWillson24Ways09],
debido a que abre la posibilidad de inyectar código de manera
directa sobre el navegador, razón por la cual las librerías
de JavaScript comenzaron a brindar mecanismos seguros para JSON.
Actualmente algunos navegadores incorporan un intérprete nativo de JSON
[MozillaMDCJSONNative09] [IEBlogNativeJSON09], que ofrece
chequeos de seguridad y un tiempo de respuesta corto. Algunas librerías
de JavaScript sacan provecho de este intérprete nativo [DaveWardEncosia2009].
JSON es ampliamente utilizado como formato de intercambio de datos en AJAX.
Un ejemplo de esta utilización se ve en el siguiente código:
var http_request = new XMLHttpRequest();
// Esta URL debería devolver datos JSON
var url = "http://example.net/jsondata.php";
// Descarga los datos JSON del servidor.
http_request.onreadystatechange = handle_json;
http_request.open("GET", url, true);
http_request.send(null);
function handle_json() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
var json_data = http_request.responseText;
var the_object = eval("(" + json_data + ")");
} else {
alert("Ha habido un problema con la URL.");
}
http_request = null;
}
}
Donde el servidor envía una respuesta de la siguiente manera:
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
El equivalente en XML es:
<menu id="file" value="File">
<popup>
<menuitem value="New" onclick="CreateNewDoc()" />
<menuitem value="Open" onclick="OpenDoc()" />
<menuitem value="Close" onclick="CloseDoc()" />
</popup>
</menu>
Google Gears
Google Gears [GGGears09] es un plugin de código abierto distribuido por Google que añade
tres componentes al navegador.
Una vez instalado como una extensión en el navegador, el producto agrega una API
que permite programar en JavaScript interacciones con los componentes que
contiene. Esta API se añade al DOM.
Los tres componentes principales que incorpora Gears son:
Local Server
Permite almacenar localmente datos correspondientes a las páginas web.
Tanto HTML, JavaScript, imágenes, etc., pueden ser almacenados
localmente por el cliente e interponerse entre el requerimiento del
navegador al servidor en consultas posteriores, evitando así la
solicitud HTTP y optimizando el tiempo de respuesta de la aplicación.
Pese a que su funcionamiento es muy similar al de la caché del navegador,
la diferencia fundamental está en que la actualización de los recursos
que almacena es realizada y mantenida por el desarrollador.
DataBase
Permite almacenar localmente datos que no correspondan a una página web
pero son parte de la lógica de la aplicación y requieren de un
almacenamiento persistente.
El motor de base de datos utilizado es SQLite con algunos agregados y
restricciones para brindar seguridad y formas de búsqueda.
Luego de que el usuario de la aplicación web otorgue el permiso explícito
de creación de la base, el desarrollador puede disponer de un almacenamiento
del tipo relacional en la máquina huésped.
Worker Pool
De manera similar a los hilos del sistema operativo, éste manejador de
hilos permite ejecutar acciones en segundo plano sin bloquear la
ejecución del hilo principal del navegador.
Hay que destacar que el manejador no corre en forma paralela a la
ejecución del navegador, sino que se ejecuta cuando la página web se
mantiene activa, por lo cual el refresco de página o la salida de la
misma provoca que éste se detenga o no se ejecute directamente.
Básicamente Gears y sus principales componentes están enfocados en permitir al
programador ejecutar sus aplicaciones cuando el navegador no está conectado
al servidor. Bret Taylor, el líder del grupo de desarrollo, dijo que buscaba ser
capaz de acceder al Google Reader mientras usaba la conexión de la compañía, la
cual frecuentemente tenía un acceso defectuoso a Internet [BretTaylor09].
Gears está incluido en el nuevo navegador de Google (Google Chrome) y
está disponible para los navegadores Internet Explorer 6.0+, Mozilla Firefox, Safari y
Opera Mini. Actualmente funciona en los sistemas operativos Windows 2000, XP y Vista,
Windows Mobile 5 y 6, MacOS y Linux de 32 bits.
A partir de la versión 0.4 se añadieron nuevas características como:
- API para GIS, para el acceso a la posición geográfica del usuario.
- API Blob, para la gestión bloques de datos binarios.
- Acceso a archivos en el equipo cliente a través de la API de Desktop.
- Envío y recepción Blobs con la API HttpRequest.
- Traducción de los cuadros de diálogo de Gears al idioma local (i18n).
- API para Canvas, para la manipulación de imágenes desde JavaScript.
Gears permite desarrollar aplicaciones en JavaScript que funcionen de manera
desconectada. Para esto se necesita instalar el plugin y la aplicación.