Ajax & Prototype Tomás Vilariño Fidalgo OUSLI 1
¿Cómo podrí a implementar un chat por http?
2
Posible solución Iframe scripting Un frame oculto se refresca por medio de javascript y se recuperan datos del servidor.
Referencias: http://developer.apple.com/internet/webcontent/iframe.html http://www.bazon.net/mishoo/rpc.epl
3
Iframe scripting es una solución compleja
“PHPOpenChat”, solución de web chat empleando Iframe scripting.
4
HTTP y aplicaciones en la Web HTTP presenta limitaciones: Es un protocolo petición/respuesta No existe un canal abierto de comunicación Después de la respuesta el servidor cierra la comunicación ●
●
●
5
Ejemplo petición HTTP
6
AJAX: la solución elegante Jesse James Garrett “bautiza” esta nueva forma
de comunicación entre cliente y servidor. AJAX no es una tecnología. Son varias Asynchronous Javascript And Xml: – – – – –
XHTML y CSS DOM XML, XSLT, XPath XMLHttpRequest (XHR) JavaScript Referencias: http://adaptivepath.com/publications/essays/archives/000385.php
7
Esquema de funcionamiento Modelo Clásico
8
Esquema de funcionamiento Modelo AJAX
9
10
Esquema de funcionamiento Modelo AJAX
1. Usuario provoca un evento 2. Se crea y configura un objeto XMLHttpRequest
3. El objeto XMLHttpRequest realiza una llamada al servidor 4. La petición se procesa en el servidor 5. El servidor retorna un documento XML (xHTML, JSON, ...) que contienen el resultado 6. El objeto XMLHttpRequest llama a la función callback() y procesa el resultado 7. Se actualiza el DOM (Document Object Model) de la página asociado con la petición con el resultado devuelto 11
Historia de Ajax Origen: Microsoft Remote Scripting (IE ActiveX Microsoft.XMLHTTP), permite trabajar con XML del servidor en el cliente IE.
Port a otros navegadores: Mozilla incorpora un objeto Javascript que realiza la misma funcionalidad XMLHttpRequest
XMLHttpRequest incluido en borrador w3c: En borrador incorporado a DOM v3 W3C Working Draft 27 February 2007 Referencias: http://www.w3.org/TR/XMLHttpRequest/
12
Conceptos previos ●
DOM, Document Object Model. Desde ECMAScript se permite manipular HTML como si fuese XML. <script language=”javascript”> var elto = document.getElementById(“id_elemento”); elto.innerHTML = “Hola mundo”;
●
Javascript y Orientación a Objetos. function miclase() { var private_var = 0; this.public_var = 1; this.metodo = function(valor){ private_var = valor; } } var instancia = new miclase(); instancia.metodo(2); miclase.prototype.nuevapropiedad = “Hola”;
●
JSON, JavaScript Object Notation. Notación de objetos literal en javascript. var obj = {id: 10, mi_array: ['nombre1', 'nombre2'], cadena: “cadena de 13 texto”};
DOM/BOM DOM manipula el árbol HTML, permite cambio de estilos CSS, renderizado de nuevo contenido, ...
14
JSON Permite definir en una cadena una estructura de datos similar a un array asociativo, pero que no deja de ser un objeto y sus las ventajas. Útil para transmitir datos con más expresividad que XML.
Referencias: http://www.json.org
15
JSONRequest Una posible alternativa a XMLHttpRequest requestNumber = JSONRequest.post( "https://json.penzance.org/request", { user: "
[email protected]", t: "vlIj", zip: 94089, forecast: 7 }, function (requestNumber, value, exception) { if (value) { processResponse(value); } else { processError(exception); } } ); POST /request HTTP/1.1 Host: json.penzance.org Content-Type: application/jsonrequest Content-Length: 72 Content-Encoding: identity Domain: www.pirate.net {"user":"
[email protected]","forecast":7,"t":"vlIj","zip":94089}
16
Comet El cliente no deberá estar solicitando los cambios de la lista de usuarios, el servidor web es el que le envía los datos al cliente cuando cambia la lista de usuarios, esto reduce considerablemente el consumo de ancho de banda.
17
¿Donde puedo encontrar Ajax? 18
Ajax en la vida real En el sitio menos pensado: Gmail, GMaps,... del.icio.us Chuza, Meneame, digg, webeame, ... Flickr, picassa, ... Youtube (Ajax + Flash) ●
●
●
●
●
19
¿Quién fue el impulsor?
G 20
Gmail Gtalk Google maps Google pages G... 21
Entorno de Trabajo 3 Reglas básicas desarrollando aplicaciones AJAX (según Thomas Fuchs): 1) Usar Firefox 2) Usar Firefox + extensiones 3) Probar en el resto de navegadores: Opera, IES4Linux, Konqueror, ...
22
●
Javascript Debugger
●
Logging para páginas web
●
DOM Inspector
●
Línea de comandos
●
Espía de peticiones Ajax (XMLHttpRequest)
●
Edición en vivo de javascript
●
CSS, edición en línea, tracking de estilos
●
Monitor de red
●
... Referencias: http://www.joehewitt.com/software/firebug https://addons.mozilla.org/firefox/1843/
23
Firebug: funcionalidades desde la consola ●
Niveles de logging: – –
●
Assertions: –
●
console.debug(“mensaje”, [,objects]); Otros niveles: info, warn, error console.assert(a, “mensaje”); // Si a es verdadero se muestra mensaje
Funciones: – – – –
$(“id”); // Atajo para document.getElementById $x(“//div”); // Expresiones xpath inspect(object); // mostrar el inspector para n objeto dir(object); // Devolver un array de propiedades del objeto 24
Debugger de firebug
25
Firebug sobre GMail
26
Complementos a Firebug ●
●
FirePHP, extensión Firefox para desarrollo PHPhttp://www.firephp.org/ FireCake, helper para CakePHP http://bakery.cakephp.org/articles/view/227
●
FireBug Lite, firebug para IE y Opera http://www.getfirebug.com/lite.html
●
Aptana
http://www.aptana.org
27
Extendiendo Firebug
http://www.firephp.org/Reference/Developers/ExtendingFire
28
Extensiones firefox: otras ●
Web Developer Toolbar: barra de herramientas que incluye diversas y útiles funcionalidades ( ¡imprescindible!)
●
Tamper Data: herramienta para la monitorización de las peticiones HTTP, incluidas las realizadas con AJAX.
●
DOM Inspector: proporciona la representación de la página actual en forma de árbol DOM.
●
Consola Javascript: incluida con firefox, muestra los errores en los script
●
Otras: IETab, Colorzilla, All-In-One sidebar, MozGestures optimoz, Venkman Debugger , greasemonkey, ... (+extensiones en mozdev.org)
Referencias: https://addons.mozilla.org/firefox/60/ (Web developer toolbar) http://tamperdata.mozdev.org/ (Tamper data)
29
Web developer, ¡imprescindible! ●
Opciones para trabajar con: – – – – –
– –
Cookies: editar, información, ... CSS: editar, deshabilitar, cambiar, ... Forms: habilitar campos, ver passwords, ... Images: imáges perdidas, información, ... Deshabilitar funcionalidades navegador: java, javascript, cache, css, ... Miscelánea: eliminar caché, cookies, ... Diseño: cuadrícula, reglas, ... 30
Web Developer Toolbar
31
Tamper Data ●
Muy buena, monitorización de las peticiones HTTP.
32
GreaseMonkey ●
●
●
●
Permite por medio de pequeñas porciones de código javascript creadas por usuarios (*.user.js), modificar el comportamiento de páginas web específicas. Con esta extensión es posible mejorar la experiencia de lectura de un sitio, hacerlo más usable, añadir nuevas funciones a páginas web, corregir errores, mejorar servicios de búsquedas y muchas otras cosas más.
Útil en el proceso de desarrollo para cumplimentar formularios de forma automática, visualizar valores del servidor, eliminar imágenes, ... http://localhost/view-session.user.js
33
Anatomía de AJAX
34
Anatomía de AJAX (I) Vamos a crear una clase AJAX que envuelva (clase wrapper) las funcionalidades específicas de cada navegador.
35
Anatomía de AJAX (II) if (window.XMLHttpRequest) { _req = new XMLHttpRequest(); _req.onload = displayState; _req.open("GET", url, true); _req.send(null); } else if (window.ActiveXObject) {
}
_req = new ActiveXObject("Microsoft.XMLHTTP"); if (_req) { _req.onreadystatechange = displayState; _req.open("GET", url, true); _req.send(); }
36
Anatomía de AJAX (III) /* Manejador del estado */ function displayState() { if(_req.readyState == 4) { if(_req.status == 200) { // Procesar datos // ... _res = _req.responseXML.documentElement; // Llamada al manejador concreto _handler(_res); } else { alert("Error recuperando datos: \n" + _req.statusText); _err += _req.statusText + '\n'; } } }
/* Llamada al manejador concreto establecido en _hdl */ function _handler(response) { if(_hdl != null) { _hdl(response); } } 37
Usando el wrapper Ajax Incluir ajax.js: <script src="ajax.js" language="javascript" type="text/javascript">
Después definir la función "manejador" que será la encargada de trabajar con los datos XML de la respuesta. <script language="javascript" type="text/javascript"> function miManejador(response) { alert( response.getElementsByTagName('resultado')[0].firstChild.data); }
Instanciar la clase AJAX y establecer el manejador definido en el paso anterior var ajax = new Ajax(); ajax.setHandler( miManejador);
Para desencadenar la llamada al manejador es necesario utilizar el método de ajax "getXML". Para ello podemos utilizar los eventos de javascript: onclick="javascript:ajax. getXML('server.php?q=1');" 38
Usando el wrapper Ajax function cargar_hora() { ajax.getXML('timeserver.php'); } var idThread = null; function init() { idThread = setInterval(cargar_hora, 5000); }
El uso de temporizadores permite realizar peticiones al servidor de forma continua hasta que se destruya el temporizador. Esto permite emular una conexi ón persistente con el servidor. 39
Usando el wrapper Ajax Para trabajar con AJAX y XSLT hay q incluir ajax.js: <script src="ajax.js" language="javascript" type="text/javascript">
La transformación del documento XML en HTML gracias a XSLT se realiza con el siguiente método: ajax.transformXML("doc.xml", "doc.xslt") var ajax = new Ajax(); var resultado = ajax.transformXML('menu.xml', “menu.xsl”);
El resultado obtenido del método transformXML es una cadena con la transformación realizada del documento XML a HTML por medio de XSLT. <script language="javascript"> var con = document.getElementById('salida'); con.innerHTML = resultado;
Referencias: 40 http://devedge.netscape.com/viewsource/2003/xslt-j
Ajax + XSLT
41
Esto es muy complejo. No existe un modo más sencillo de trabajar con Ajax?
42
Frameworks AJAX ●
Mediante reflexión determinan la interfaz de las clases del lado servidor y generan código javascript para invocar funcionalidades desde el cliente. – –
–
●
JPSpan y Sajax, en PHP5. DWR, en Java, posibilidad de integrar con otros frameworks como struts. DWR 2.0 introduce el concepto de Reverse Ajax (desde el servidor enviar javascript al cliente :-O ). Ajax.NET.
Librerías javascript que permiten funcionalidades AJAX: –
script.aculo.us, mejor dicho prototype
–
Dojo, integrada en DWR
43
Framework Prototype ●
●
PROTOTYPE (http://prototype.conio.net/) es un framework desarrollado en JavaScript por Sam Stephenson para el desarrollo sencillo y dinámico de páginas WEB. PROTOTYPE simplifica gran parte del trabajo cuando se pretende desarrollar páginas altamente interactivas. [def.wikipedia: http://es.wikipedia.org/wiki/Prototype]
44
¿Por qué Prototype? ●
●
●
●
Ruby On Rails, Perl, Nitro, PHP, Java, Plone, Pylons, DotNet, Symfony, Seaside, AIDA/Web, OpenACS, Django, CakePHP Sencillo y potente OO y extensible Herramientas integran prototype (Aptana)
45
Framework Prototype ●
Métodos de utilidad: $(), $F(), $A(), $$(), ...
●
Ajax
●
Array, Hash, String
●
Class, Object, Function
●
Date, Element, Enumerable, Number
●
Event, Position
●
Form
●
Insertion, Template
●
PeriodicalExecuter, TimedObserver ●
http://www.prototypejs.org/api 46
Ejemplos con Prototype ●
Facilita la programación OO: Helper = Class.create(); Helper.prototype = Object.extend(Helper, { initialize: function(element, url, options) { this.element = $(element); ... }}); http://localhost/ajax/js/helper.js
●
Extiende objetos básicos de Javascript para proporcionar nuevas funcionalidades: String, Array, Hash, ... –
47
Ajax con Prototype, por fin
">
<script language="javascript"> new Ajax Ajax.PeriodicalUpdater(' .PeriodicalUpdater('contenido contenido', ', 'timeserver.php timeserver.php', ', {method: 'get', frequency: 3, decay: 2}); '.$hora.''); ?> 48
Ajax Options, opciones comunes de los distintos objetos Ajax Ajax.PeriodicalUpdater – –
new Ajax.PeriodicalUpdater(container, url[, options]) Realiza unas llamadas de forma periódica actualizando el contenido “container” con la respuesta basada en texto. Ofrece un mecanismo de “decay” (decaer, putrefacción) que comprueba las respuesta e incrementa los períodos de petición automáticamente. http://prototypejs.org/api/ajax/periodicalUpdater http://localhost/ajax/timeclient.htm
El objeto más básico y potente de petición AJAX. 49
Es un repositorio global de monitores que notifican todos los pasos de las peticiones Ajax (Prototype).
new Ajax.Updater(container, url[, options]) Realiza una petición AJAX y actualiza el contenedor con el texto de la respuesta.
Script.aculo.us está implementado empleando prototype para proporcionar nuevas funcionalidades: – – – –
Efectos (Effects) Controles visuales (Controls) Utilidades (Utils) Pruebas (Testing)
Uso: <script src="javascripts/prototype.js" type="text/javascript"> <script src="javascripts/scriptaculous.js" type="text/javascript"> 51
<script type="text/javascript" language="javascript"> Effect.Appear('element_id');
La última versión 1.7.0 añade nuevos efectos: Effect.Transform, Effect.Morph, ... inspirados en el framework de Bernie's: http://berniecode.com/writing/animator.html
Un Mashup es un sitio web o una aplicación que combina contenidos/servicios de varias fuentes integradas de modo que parezca una única aplicación. (Flickr + Weblog + GMaps) http://localhost/ajax/google-suggest.php
Builder es una clase de script.aculo.us que permite manipular DOM de forma más sencilla sin tener que trabajar con document.createElement, document.createTextNode, .... http://localhost/ajax/builder.htm
table = Builder.node('table', {width:'100%', cellpadding:'2', cellspacing:'0',border:'0'}); tbody = Builder.node('tbody'); tr = Builder.node('tr',{className:'header'}); td = Builder.node('td',[ Builder.node('strong','Category')]); tr.appendChild(td); tbody.appendChild(tr); table.appendChild(tbody); $('contenido').appendChild(table); 56
Proyecto de OUSLI empleando: prototype, scriptaculous, ADOdb, Smarty, MySQL, ... Pizarra de trabajo colaborativo vía web Un usuario puede publicar notas, en las distintas pizarras categorizadas por temas, y en tiempo real ver los post-it publicados por los otros usuarios. http://localhost/brainstorming/login.php 57
Ahora con CakePHP Extraído del tutorial: http://grahambird.co.uk/cake/tutorials/
Lista de tareas pendientes 1.- Primero es necesario incluir las últimas versiones de prototype y script.aculo.us. Descargan script.aculo.us ya tenemos ambas incluidas. http://script.aculo.us/downloads
2.- Incluír en /app/views/layouts/default.thtml los tags para trabajar con script.aculo.us y prototype: charsetTag(' UTF-8') ?> link('prototype') ?> link('scriptaculous.js?load=effects') ?>
CakePHP y Ajax 4.- El modelo es el mismo que el empleado para el trabajo sin Ajax 5.- El controlador tiene en cuenta el layout con el que está trabajando a la hora de ejecutar el render. http://ajax.localhost/tasks_controller.phps
function add() {... $this->render('todo', 'ajax'); ...}
CakePHP y Ajax 6.- En la vista es donde está (y donde debe estar) todo el meollo de Ajax. http://ajax.localhost/tasks/
Ajax tiene detractores pero seguramente sea por desconocimiento. Razones para usar Ajax:
1.- Este modelo de trabajo es complementario al anterior. 2.- Inconvenientes de accesibilidad, “botón atrás”, “marcadores”, ... son solucionables 3.- Se mejora la usabilidad de la aplicación empleando Ajax: tiempos de respuesta, ... (Gmail) 4.- Se está trabajando en aplicaciones web offline. Apollo de Adobe, Dojo toolkit, Mozilla 5.- Google está trabajando con esta tecnología, por algo será!!! 6.- ... 61
IExploter es el inconveniente más grande que evita la verdadera explosión de esta tecnología M$ no le interesa que este tipo de aplicaciones avancen. Tiene mucho mercado en aplicaciones de escritorio (Office) Aparecen nuevos frameworks que facilitan el trabajo en cliente y servidor en un mismo lenguaje: haXe, GWT, ... Gracias a una oferta tan importante de herramientas en Software Libre sería muy raro que esto sólo sea una burbuja. 62