NF1 - AJAX
Contingut
AJAX
Ajax significa Asynchronous JavaScript i XML, un terme que va ser encunyat per Jesse James Garrett en Adaptive Path, el febrer de 2005. S'hi descriu una metodologia de desenvolupament d'aplicacions web d'una manera diferent a la tradicional. Segons l'article, les aplicacions web i llocs tradicionals funcionen sincrònicament-cada vegada segueix un enllaç, o quan s'envia un formulari, el navegador envia les dades al servidor, el servidor (amb sort) respon, i tota la pàgina s'actualitza. Aplicacions Ajax funcionen de forma asíncrona, el que significa que envies dades d'anada i tornada entre el navegador i el servidor sense haver de recarregar tota la pàgina. Substitueix només les parts de la pàgina que canvia.
[Exemple gràfic http://www.funcion13.com/wp-content/uploads/2012/01/ajax-explicado-vineta.jpg]
El realment bo d'això és que la comunicació entre el motor Ajax i el navegador passa a través de JavaScript i no a través de carregar la pàgina. En termes pràctics, això significa per a l'usuari final menys temps d'espera per carregar les pàgines i la visualització, i més fàcil la interacció amb la pàgina, per que pots sol·licitar dades i continuar llegint el text o el contingut d'una altre part de la pàgina.
Els principals elements d'AJAX
Ajax no és una tecnologia única. Més aviat, és una col·lecció de quatre tecnologies que es complementen:
Tecnologia | Expliació |
---|---|
JavaScript | És un llenguatge de scripting de propòsit general dissenyat per a ser integrat dins les aplicacions. L'intèrpret de JavaScript en un navegador web permet la interacció programàtica amb moltes de les capacitats incorporades del navegador. Aplicacions Ajax estan escrits en JavaScript. |
Cascading Style Sheets (CSS) | Ofereix una forma de definir els estils visuals reutilitzables per a elements de la pàgina web. Ofereix una forma senzilla i potent de definir i aplicar un estil visual consistent. En una aplicació Ajax, l'estil d'una interfície d'usuari es pot ajustar de forma interactiva a través de CSS. |
Document Object Model (DOM) | El DOM presenta l'estructura de les pàgines web com un conjunt d'objectes programables que poden ser manipulats amb JavaScript. Scripts del DOM permet a una aplicació Ajax modificar la interfície d'usuari sobre la marxa, tornar a dibuixar de manera efectiva les parts de la pàgina. |
XMLHttpRequest object (XHR) | El objecte XMLHttpRequest permet que els programadors web recuperarin les dades des del servidor web com una activitat de fons. El format de dades és típicament XML, però funciona bé amb totes les dades basades en text. |
Funcionament
L'objecte XHR ens permet fer peticions HTTP al servidor i rebre la resposta mitjançant programació , en lloc que el navegador doni automàticament la resposta com una nova pàgina . El primer que hem de fer és crear un objecte XHR. A continuació , proporcionar-li la informació que necessita per realitzar la sol·licitud i finalment , gestionar la resposta quan ens la donen.Entre l'enviament de la sol·licitudi la recepció de la resposta , hi ha feina per fer en el servidor, i algunes linies més de codi que hem d'escriure en PHP, Java, .NET o qualsevol altre.
Ens interessa principalment el codi del costat del client, a més la mecànica del costat del servidor de maneig d'una senzilla petició Ajax no són molt diferents de programació web pre-Ajax.
El API XMLHttpRequest
El cor d'AJAX és una API anomenada XMLHttpRequest(XHR), disponible en els llenguatges de scripting en el costat del client,com ara JavaScript. S'utilitza per realitzar peticions, HTTP o HTTPS, directament al servidor web, i per carregar les respostes directament a la pàgina del client. Les dades que rebem des del servidor es poden rebre en forma de text pla o text XML. Aquestes dades podran ser utilitzats per modificar el DOM del document actual, sense haver de recarregar la pàgina, o també podran ser avaluats amb JavaScript, si són rebuts en format JSON. XMLHttpRequest juga un paper molt important en la tècnica AJAX, ja que sense aquest objecte, no seria possible realitzar les peticions asíncrones al servidor. Una de les limitacions de XMLHTTPR equest és que, per seguretat, només ens deixa realitzar peticions AJAX, a les pàgines que es trobin allotjades en el mateix domini, des del qual s'està realitzant la petició AJAX.
L'objecte XHR (XMLHttpRequest)
En un món perfecte, el codi escrit per a un navegador funcionaria en tots els navegadors. Ja hem après que no vivim en aquest món, i les coses no són diferents quan es tracta d'Ajax. Hi ha una manera estàndard de fer peticions asíncrones a través de l'objecte JavaScript XHR, i una manera patentada Internet Explorer que utilitza un control ActiveX. Amb IE 7, un embolcall que emula la interfície estàndard està disponible, però IE 6 requereix codi diferent. Un cop creat l'objecte XHR, el codi per configurar, iniciar i respondre a la sol·licitud és relativament independent del navegador, i la creació d'una instància de XHR és fàcil per a qualsevol navegador en particular. El problema és que els diferents navegadors implementen XHR de diferents maneres, i hem de crear la instància de la manera adequada per al navegador actual. Utilitzarem la técnica featured detection per averiguar quin objecte XHR podem crear pel navegador actual. Exemple de la creació d'aquest Objecte:
var xhr; if (window.ActiveXObject) { //Iexplorer xhr = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { //Tots els altres navegadors que soporten ajax xhr = new XMLHttpRequest(); } else { throw new Error("Ajax is not supported by this browser"); }
Mètodes i propietats de l'objecte XHR
Primer donem una ullada als mètodes del Objecte XMLHttpRequest:
Mètode | Descripció |
---|---|
abort() | Fa que la Sol·licitud que s'està executant sigui cancel·lada. |
getAllResponseHeaders() | Retorna una cadena que conté els noms i valors de totes les capçaleres de resposta. |
getResponseHeader(name) | Retorna el valor de la capçalera de la resposta anomenada 'named'. |
open(method,url,async, username,password) | Estableix el mètode HTTP (GET o POST) i l'URL de destinació de la sol·licitud. Opcionalment, la sol·licitud pot ser declarada síncrona (async=false), i es pot subministrar un nom d'usuari i contrasenya per a les sol·licituds que requereixen autenticació. |
send(dades) | dades: S'usa en el cas que estiguem utilitzant el mètode POST, com a mètode d'enviament.Si fem servir GET, dades serà null |
setRequestHeader(name,value) | Afegeix el parell etiqueta / valor a la capçalera de dades que s'enviarà al servidor |
Exemples amb els diferents mètodes de enviament d'informació (GET i POST):
- Exemple amb GET: Amb el mètode GET els paràmetres es passen a la mateixa URL.
xmlhttp.open("GET", "datos.php?curso=SMX1&tutor=Julio+Noguera", true);
xmlhttp.send(null);
- Exemple amb POST: Con el método POST los parámetros se pasan con la función datos.send().
xmlhttp.open("POST","datos.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("curso=SMX1&tutor=Julio+Noguera");
si no s'estableix la capçalera "Content-Type" correcta, el servidor descarta totes les dades enviades mitjançant el mètode POST. D'aquesta manera, al programa que s'executa en el servidor no li arriba cap paràmetre. Així, per enviar paràmetres mitjançant el mètode POST, és obligatori incloure la capçalera "Content-Type"
Propietats del Objecte XMLHttpRequest:
L'objecte XMLHttpRequest, disposa de les següents propietats, que ens faciliten informació sobre el estat de la petició al servidor, i on rebrem les dades de la resposta retornada a la petició AJAX:
Propietat | Descripció |
---|---|
onreadystatechange | Emmagatzema una funció (o el nom d'una funció), que serà cridada automàticament, cada vegada que es produeixi un canvi en la propietat readyState. |
readyState | Emmagatzema l'estat de la petició XMLHTTPRequest. Possibles estats, del 0 al 4:
0: sol·licitud no inicialitzada. 1: connexió establerta amb el servidor. 2: sol·licitud rebuda. 3: processant sol·licitud. 4: sol·licitud ja acabada i la resposta està disponible. |
responseText | Conté les dades de resposta, com una cadena de text. |
responseXML | Si es responseText és XML aqui trobem l'arbre XML DOM associat. Datos devueltos por el servidor en forma de documento XML que puede ser recorrido mediante las funciones del DOM (getEementsByTagName, etc.).Retorna un [object XMLDocument] |
status | El codi d'estat de resposta retornat pel servidor. Per exemple: 200 per a l'èxit o el 404 perquè no es troba. Consulteu l'especificació HTTP per a tot el conjunt de codis. |
statusText | El missatge de text de l'estat retornat pel servidor. (per exemple: "Not Found" o "OK"). |
Utilització de l'objecte XHR
Ara que tenim una instància XHR creada, donem una ullada al que es necessita per configurar i executar la sol·licitud al servidor.
- Especificar un mètode HTTP com GET o POST
- Especificar la URL del servidor al que demanarem la informació a mostrar a l'usuari
- Especificar a l'objecte XHR la manera que volem saber del progrès de la petició
- Especificar la informació a enviar al servidor (content).
Amb la següent sentencia javascript especifiquem els primers dos items del llistat anterior:
xhr.open('GET', 'url');
o
xhr.open('POST', 'url');
Tingues en compte que la sentencia anterior no envia res al servidor, només estem configurant l'objecte per tal que utilitzi un servidor i un mètode de conexió HTTP.
El tercer item diu que hem de dotar a l'objecte XHR amb un mecanisme d'avís per fer-nos saber com va la petició ajax. Per fer-ho, s'ha d'assignar una funció de resposta (callback function) a la propietat onreadystatechange del objecte XHR. Aquesta funció l'executarà l'objecte XHR en diverses ocasions, segons l'estat amb el que es trobi l'objecte.
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300) {
// només ens interesa si la petició al servidor
// s'ha completat i ha estat correcta.
}
else {
// problema amb la petició
}
}
}
A l'últim item s'ha d'especificar, si hi ha, la informació necessaria que necessita saber el servidor per tal de processar correctament la petició. Finalment, enviar la petició. Aixó s'aconsegueix amb el mètode send() de l'objecte XHR.
xhr.send("a=1&b=2");
Resposta del servidor mitjançant l'objecte XHR
Una vegada s'ha completat la petició al servidor podem agafar la seva resposta (response) del objecte XHR. El format de la resposta pot ser qualsevol format en mode TEXT; no està limitat a XML. De fet, la majoria del temps, la resposta de Ajax és un altre format. Aquest pot ser text planer, un fragment HTML o pot ser una representació d'objecte de JavaScript com és JSON.
Sigui quin sigui el format del text, la resposta es pot obtenir mitjançant la propietat responseText del objecte XHR. Si la resposta està en format XML, per que s'ha especificat utilitzant el tipus MIME text/xml o application/xml, es tractada i es crea un arbre DOM que està disponible a la propietat responseXML del objecte XHR.
Una vegada tenim la resposta del servidor la hem de carregar al element DOM apropiat.
Exemple:
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300) {
document.getElementById('someContainer').innerHTML = this.responseText;
}
}
}
EXEMPLE
var objetoXHR = new XMLHttpRequest();
function obtenerDatosServidor(origen, elemento) //Función “obtenerDatosServidor” contiene dos parámetros
{
var objeto_destino = document.getElementById(elemento); // Se elige el elemento HTML a ser modificado.
objetoXHR.open(“GET”, origen); //Se configura una conexión asíncrona con una URL.
objetoXHR.onreadystatechange = respuesta(); // Se indica la función a ser llamada una vez el estado
// del objeto cambie.
objetoXHR.send(null); // Se abre la conexión.
}
function respuesta()
{
if (objetoXHR.readyState == 4 && objetoXHR.status == 200)
{
objeto_destino.innerHTML = objetoXHR.responseText;
}
}
GET con AJAX
<script type="text/javascript">
var datos;
function pedir_datos (url, params) {
datos = new XMLHttpRequest();
datos.open("GET", url+ ' ?' +params , true);
datos.onreadystatechange = mostrar_datos;
datos.send(null);
}
function mostrar_datos () {
if (datos.readyState == 4 && datos.status == 200)
document.getElementById('resultado').innerHTML = datos.responseText;
}
function iniciar() {
var url = 'get.php';
var params = f.curso.name +'='+ f.curso.value +'&'+ f.tutor.name +'='+ f.tutor.value;
pedir_datos(url, params);
}
</script>
</head>
<body>
<form name="f" method="get" action="javascript: iniciar ()">
<label>Curso: </label>
<select name="curso">
<option value="SMX1" > SMX1 </option>
<option value="SMX2" selected> SMX2 </option>
</select>
<label>Tutor: </label>
<input type="text" name="tutor" value="Julio Noguera" />
<input type="submit" name="submit" value="OK" />
</form>
<div id="resultado"> </div>
POST con AJAX
<script type="text/javascript">
var datos;
function pedir_datos (url, params) {
datos = new XMLHttpRequest();
datos.open("POST", url, true);
datos.onreadystatechange = mostrar_datos;
datos.setRequestHeader("Content-type", "application/xwwwformurlencoded");
//datos.setRequestHeader("Contentlength", params.length);
datos.setRequestHeader("Connection", "close");
datos.send(params);
}
function mostrar_datos () {
if (datos.readyState == 4 && datos.status == 200)
document.getElementById('resultado').innerHTML = datos.responseText;
}
function iniciar() {
var url = 'post.php';
var params = f.curso.name +'='+ f.curso.value +'&'+ f.tutor.name +'='+ f.tutor.value;
pedir_datos(url, params);
}
</script>
</head>
<body>
<form name="f" method="post" action="javascript: iniciar()">
<label>Curso: </label>
<select name="curso">
<option value="SMX1" > SMX1 </option>
<option value="SMX2" selected> SMX2 </option>
</select>
<label>Tutor: </label>
<input type="text" name="tutor" value="Julio Noguera" />
<input type="submit" name="submit" value="OK" />
</form>
<div id="resultado"> </div>
Exercicis
Per realitzar aquest exercicis es necessita una màquina virtual amb els programes apache i php5 instalats.
Exercici 1
Crea una petició amb AJAX per tal de conèixer els paràmetres de configuració del php. Et recordo que per obtenir-los només cal executar la funció de php anomenada phpinfo();
Exercici 2
Realitzar un exercici que mostri per pantalla en quin estat de petició està (1 al 4) per pantalla, per a això s'haurà d'afegir en un fitxer anomenat espera a php o jsp amb una pausa de tres segons i quan acabi haurà de mostrar el temps abans i després d'aquest temps.
Exercici 3
Crea dos camps (nom i cognom). Envia la informació mitjançant AJAX al servidor PHP i fes que et retorni els valors passats a majúscules. Insereix directament amb HTML la informació a un DIV de la pàgina.
Exercici 4
Desplegables encadenats. Es vol crear 2 desplegables en HTML que la seva informació la obtingui del servidor mitjançant AJAX. El primer Desplegable ha de contenir les següents ciutats: Barcelona, Madrid, Sevilla, LaCoruña. El segon desplegable mostrarà els Barris de la Ciutat escollida al primer desplegable.
Exercici 5
- a)Crea un formulari que demani nom d'usuari i contrasenya. Crea un botó de validació que validi amb AJAX que l'usuari introduït no existeixi. Si existeix s'ha de proposar un nom alternatiu. Com no utilitzarem BD crea un fitxer on a cada linia hi hagi un nom d'usuari. El nou nom d'usuari no ha de coincidir amb cap dels noms que apareix a la llista.
- b)Crea un Botó anomenat enviar que mitjançant AJAX envii el nom d'usuari i la contrasenya al servidor. El nom d'usuari s'ha d'afegir al fitxer anterior.
Exercici 6
Es tracta de crear un input que s'introduiran noms i mitjançant ajax consultar la base de dades si hi ha el nom en cas d'existir ha de mostrar tots els noms que comencen amb les lletres introduïdes
Referències
- http://www.w3schools.com/ajax/default.ASP
- https://developer.mozilla.org/en-US/docs/AJAX
- https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
- http://www.xul.fr/en-xml-ajax.html
Bibliografia
Bear Bibeault, Yehuda Katz, "JQuery in Action Second Edition", Ed. Manning, 2010, ISBN 978-935182-32-0
Dace Crane, Bear Bibeault, Jord Sonneveld,"Ajax in Practice", Ed. Manning, 2007, ISBN 1-932394-99-0
Christian Heilmann, "Beginning JavaScript with DOM Scripting and Ajax", Ed. Apress, 2006, ISBN 1-59059-680-3