11 B Ajax
11 B Ajax
Ajax
Giovanni Grasso
Un nuovo modello
L’utilizzo di DHTML (JavaScript/Eventi + DOM + CSS)
delinea un nuovo modello per applicazioni Web
=> Modello a eventi simile a quello delle applicazioni
tradizionali
Abbiamo però due livelli di eventi:
Eventi locali che portano ad una modifica diretta
DOM da parte di Javascript e quindi a cambiamento
locale della pagina
Eventi remoti ottenuti tramite ricaricamento della
pagina che viene modificata lato server in base ai
parametri passati in GET o POST
Il ricaricamento di pagina per rispondere a interazione
con l’utente prende il nome di postback
2
Modello a eventi a due livelli
Risposta locale
Servlet/
JavaScript JSP
Postback
Web
Server
DOM Bean
3
Esempio di evento remoto - 1
Consideriamo un form in cui compaiono due tendine che
servono a selezionare il comune di nascita di una
persona
Una con province
Una con comuni
4
Esempio di evento remoto - 2
Per realizzare questa interazione si può procedere in
questo modo:
Si crea JSP che inserisce nella tendina dei comuni
l’elenco di quelli che appartengono alla provincia
passata come parametro
Si definisce un evento onchange collegato
all’elemento select delle province
Lo script collegato ad onchange forza il
ricaricamento della pagina con un POST (postback)
Quindi:
L’utente sceglie una provincia
Viene invocata la JSP con parametro provincia
impostato al valore scelto dall’utente
La pagina restituita contiene nella tendina dei
comuni l’elenco di quelli che appartengono alla
provincia scelta
5
Limiti del modello a ricaricamento di pagina
Quando lavoriamo con applicazioni desktop siamo
abituati a un elevato livello di interattività:
applicazioni reagiscono in modo rapido ed intuitivo
ai comandi
Le applicazioni Web tradizionali espongono invece un
modello di interazione rigido
Modello “Click, wait, and refresh”
È necessario refresh della pagina da parte del
server per la gestione di qualunque evento
(sottomissione di dati tramite form, visita di link per ottenere
informazioni di interesse, …)
È ancora modello sincrono: l’utente effettua una
richiesta e deve attendere la risposta da parte del
server
6
Modello di interazione classico
7
AJAX e asincronicità
Il modello AJAX è nato per superare queste limitazioni
AJAX non è un acronimo ma spesso viene interpretato
come Asynchronous Javascript And Xml
È basato su tecnologie standard:
JavaScript
DOM
XML
HTML
CSS
8
AJAX e asincronicità
AJAX punta a supportare applicazioni user friendly
con elevata interattività (si usa spesso il termine RIA -
Rich Interface Application)
L’idea alla base di AJAX è quella di consentire agli
script JavaScript di interagire direttamente con il
server
Si usa oggetto JavaScript XMLHttpRequest
Consente di ottenere dati dal server senza la
necessità di ricaricare l’intera pagina
Realizza una comunicazione asincrona fra client e
server: il client non interrompe interazione con
utente anche quando è in attesa di risposte dal
server
9
Modello di interazione con AJAX
10
Tipica sequenza AJAX
Si verifica un evento determinato dall’interazione fra
utente e pagina Web
L’evento comporta l’esecuzione di una funzione
JavaScript in cui:
Si istanzia un oggetto di tipo XMLHttpRequest
Si configura XMLHttpRequest: si associa una
funzione di callback, si effettua configurazione, …
Si effettua chiamata asincrona al server
Il server elabora la richiesta e risponde al client
Il browser invoca la funzione di callback che:
elabora il risultato
aggiorna il DOM della pagina per mostrare i risultati
dell’elaborazione
11
XMLHttpRequest
L’oggetto XMLHttpRequest effettua la richiesta di una
risorsa via HTTP a server Web
Non sostituisce l’URI della propria richiesta all’URI
corrente
Non provoca un cambio di pagina
Può inviare eventuali informazioni (parametri) sotto
forma di variabili (come una form)
Può effettuare sia richieste GET che POST
Le richieste possono essere di tipo
Sincrono: blocca flusso di esecuzione del codice
Javascript (ci interessa poco)
Asincrono: non interrompe il flusso di esecuzione
del codice Javascript né le operazioni dell'utente
sulla pagina
12
Creazione di un’istanza
I browser più recenti (Firefox 1+, Opera 7+, Safari,
Internet Explorer 7 e 8) supportano XMLHttpRequest
come oggetto nativo
In questo caso (oggi il più comune) le cose sono molto
semplici:
var xhr = new XMLHttpRequest();
La gestione della compatibilità con browser più vecchi
complica un po’ le cose; --> JQuery!
13
Metodi di XMLHttpRequest
La lista dei metodi disponibili è diversa da browser a
browser
14
Metodo open()
open() ha lo scopo di inizializzare la richiesta da
formulare al server
15
Metodi setRequestHeader() e send()
setRequestHeader(nomeheader, valore) consente di impostare
gli header HTTP della richiesta da inviare
Viene invocata più volte, una per ogni header da impostare
Per una richiesta GET gli header sono opzionali
Sono invece necessari per impostare codifica utilizzata nelle
richieste POST
È comunque importante impostare l’header connection al
valore close per evitare di aprire troppe connessioni
16
Esempi
GET
var xhr = new XMLHttpRequest();
xhr.open("get","pagina.html?p1=v1&p2=v2", true );
xhr.setRequestHeader("connection", "close");
xhr.send(null);
POST
var xhr = new XMLHttpRequest();
xhr.open("post","pagina.html", true );
xhr.setRequestHeader("content-type",
"x-www-form-urlencoded");
xhr.setRequestHeader("connection","close");
xhr.send("p1=v1&p2=v2");
17
Proprietà di XMLHttpRequest
Stato e risultati della richiesta vengono memorizzati
dall’interprete Javascript all’interno dell’oggetto
XmlHttpRequest durante la sua esecuzione
18
Proprietà ReadyState
Proprietà in sola lettura di tipo intero che consente di
leggere in ogni momento lo stato della richiesta
ammette 5 valori:
0: uninitialized - l'oggetto esiste, ma non è stato
richiamato open()
1: open - è stato invocato il metodo open(), ma
send() non ha ancora effettuato l'invio dati
2: sent - metodo send() è stato eseguito e ha
effettuato la richiesta
3: receiving – la risposta ha iniziato ad arrivare
4: loaded - l'operazione è stata completata
Attenzione:
Questo ordine non è sempre identico e non è
sfruttabile allo stesso modo su tutti i browser
L'unico stato supportato da tutti i browser è il 4
19
Proprietà onreadystatechange
Come si è detto l'esecuzione del codice non si blocca
sulla send() in attesa dei risultati
Per gestire la risposta si deve quindi adottare un
approccio a eventi
Occorre registrare una funzione di callback che viene
richiamata in modo asincrono ad ogni cambio di stato
della richiesta
La sintassi è
xhr.onreadystatechange = nomefunzione
xhr.onreadystatechange = function(){istruzioni}
20
Proprietà status e statusText
status contiene un valore intero corrispondente al
codice HTTP dell’esito della richiesta:
200 in caso di successo (l’unico in base al quale i dati
ricevuti in risposta possono essere ritenuti corretti e
significativi)
Possibili altri valori (in particolare d’errore: 403,
404, 500, …)
21
Proprietà responseText e responseXML
Contengono i dati restituiti dal server
responseText: stringa che contiene il body della
risposta HTTP
disponibile solo a interazione ultimata
(readystate==4)
22
Metodi getResponseHeader(), getAllResponseHeaders()
Consentono di leggere gli header HTTP che descrivono
la risposta del server
Sono utilizzabili solo nella funzione di callback
Possono essere invocati sicuramente in modo safe
solo a richiesta conclusa (readystate==4)
Sintassi:
getAllResponseHeaders()
getResponseHeader(header_name)
23
Ruolo della funzione di callback
Viene invocata ad ogni variazione di readystate
Usa readystate per leggere lo stato di avanzamento
della richiesta
Usa status per verificare l’esito della richiesta
Ha accesso agli header di risposta rilasciati dal server
con getAllResponseHeaders() e
getResponseHeader()
Se readystate==4 può leggere il contenuto della
risposta con responseText e responseXML
24
Esempio
Attenzione: anche se la funzione è assegnata a una
proprietà di xhr, dal suo interno NON è possibile
riferirsi a xhr con this. Questo perché la funzione viene
richiamata in modo asincrono dall’interprete
25
Vantaggi e svantaggi di AJAX
Si guadagna in espressività, ma si perde la linearità
dell'interazione
Mentre l'utente è all'interno della stessa pagina le
richieste sul server possono essere numerose e
indipendenti
Il tempo di attesa passa in secondo piano o non è
avvertito affatto
Possibili criticità sia per l’utente che per lo
sviluppatore
percezione che non stia accadendo nulla (sito che
non risponde)
problemi nel gestire un modello di elaborazione che
ha bisogno di aspettare i risultati delle richieste
precedenti
26
Criticità nell’interazione con l’utente
Le richieste AJAX permettono all’utente di continuare
a interagire con la pagina
Ma non necessariamente lo informano di che cosa stia
succedendo e possono durare troppo!
L’effetto è un possibile disorientamento dell’utente
Dobbiamo quindi agire su due fronti:
Rendere visibile in qualche modo l’andamento della
chiamata (barre di scorrimento, info utente, …)
Interrompere le richieste che non terminano in
tempo utile per sovraccarichi del server o
momentanei problemi di rete (timeout)
27
Il metodo abort()
abort() consente l’interruzione delle operazioni di invio
o ricezione
non ha bisogno di parametri
termina immediatamente la trasmissione dati
Attenzione: non ha senso invocarlo dentro la funzione di
callback
Se readyState non cambia, il metodo non viene richiamato;
readyState non cambia quando la risposta si fa attendere
Si crea un’altra funzione da far richiamare in modo
asincrono al sistema mediante il metodo
setTimeOut(funzioneAsincronaPerAbortire,timeOut)
Al suo interno si valuta se continuare l’attesa o
abortire l’operazione
28
Gestire la risposta
Spesso i dati scambiati fra client e server sono
codificati in XML
AJAX come abbiamo visto è in grado di ricevere
documenti XML
In particolare è possibile elaborare i documenti XML
ricevuti utilizzando API W3C DOM
32
Esempio:
Scegliamo un nome da una lista e mostriamo i suoi dati
tramite Ajax
<html>
<head>
<script src="selectmanager_xml.js"></script>
</head>
<body>
<form action=""> Scegli un contatto:
<select name=”manager“
onchange="showManager(this.value)">
<option value=”Carlo11">Carlo Rossi</option> Lista di
<option value=”Anna23">Anna Bianchi</option> selezione
<option value=”Giovanni75">Giovanni Verdi</option>
</select></form>
<b><span id="companyname"></span></b><br/>
<span id="contactname"></span><br/>
Area in cui
<span id="address"></span> mostrare i
<span id="city"></span><br/> risultati
<span id="country"></span>
</body>
</html>
33
Esempio - 2
Ipotizziamo che i dati sui contatti siano contenuti in un
database. Il server:
riceve una request con l’identificativo della persona
interroga il database
restituisce un file XML con i dati richiesti
34
Esempio: selectmanager_xml.js
var xmlHttp;
function showManager(str)
{ xmlHttp=new XMLHttpRequest();
var url="getmanager_xml.jsp?q="+str;
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function stateChanged()
{ if (xmlHttp.readyState==4)
{
var xmlDoc=xmlHttp.responseXML.documentElement;
var compEl=xmlDoc.getElementsByTagName("compname")[0];
var comName = compEl.childNodes[0].nodeValue;
document.getElementById("companyname").innerHTML=
compName;
...
}
}
35
XML è la scelta giusta?
Secondo un’interpretazione molto comune la X di
AJAX sta per XML
Abbiamo però visto nell’esempio precedente che
l’utilizzo di XML come formato di scambio fra client e
server porta alla scrittura di codice molto prolisso
Difficile da leggere e da manutenere
Oneroso in termini di risorse di elaborazione (non
dimentichiamo che JavaScript è interpretato)
36
JSON
JSON è l’acronimo di JavaScript Object Notation
Formato per lo scambio di dati, considerato molto più
comodo di XML
Leggero in termini di quantità di dati scambiati
Molto semplice da elaborare per un linguaggio di
programmazione (in particolare per JavaScript)
Ragionevolmente semplice da leggere per
operatore umano
È largamente supportato dai maggiori linguaggi di
programmazione
Si basa sulla notazione usata per le costanti oggetto
(object literal) e le costanti array (array literal) in
JavaScript
37
Oggetti e costanti oggetto
In Javascript è possibile creare un oggetto in base a
una costante oggetto
var Beatles =
{
"Paese" : "Inghilterra",
"AnnoFormazione" : 1959,
"TipoMusica" : "Rock"
}
38
Array e costanti array
In modo analogo è possibile creare un array utilizzando
una costante di tipo array:
var Membri =
["Paul","John","George","Ringo"];
Che equivale in tutto e per tutto a
var Membri =
new Array("Paul","John","George","Ringo");
Possiamo anche avere oggetti che contengono array:
var Beatles =
{
“Paese" : “Inghilterra",
“AnnoFormazione" : 1959,
“TipoMusica" : "Rock",
"Membri" : ["Paul","John","George","Ringo"]
}
39
Array di oggetti
È infine possibile definire array di oggetti:
var Rockbands = [
{
"Nome" : "Beatles",
“Paese" : “Inghilterra",
“AnnoFormazione" : 1959,
“TipoMusica" : "Rock",
"Membri" : ["Paul","John","George","Ringo"]
},
{
"Nome" : "Rolling Stones",
“Paese" : “Inghilterra",
“AnnoFormazione" : 1962,
“TipoMusica" : "Rock",
"Membri" : ["Mick","Keith","Charlie","Bill"]
}
]
40
La sintassi JSON
La sintassi JSON si basa su quella delle costanti
oggetto e array di Javascript
Un “oggetto JSON” è una stringa che equivale a una
costante oggetto di JavaScript, dove le key sono tra ""
Costante oggetto Javascript
{
“Paese" : “Inghilterra",
“AnnoFormazione" : 1959,
“TipoMusica" : "Rock'n'Roll",
"Membri" : ["Paul","John","George","Ringo"]
}
41
Da String JSON a Oggetto
44
JSON e AJAX - 1
Sul lato client:
Si crea un oggetto JavaScript e si riempiono le sue
proprietà con le informazioni necessarie
Si usa JSON.stringify() per convertire l’oggetto
in stringa JSON
Si usa la funzione encodeURIComponent() per
convertire la stringa in un formato utilizzabile in
una richiesta HTTP
Si manda la stringa al server mediante
XMLHttpRequest (stringa viene passata come
variabile con GET o POST)
45
JSON e AJAX - 2
Sul lato server:
Si decodifica la stringa JSON e la si trasforma in
oggetto Java utilizzando un apposito parser (GSON,
Jackson, altri sul json.org)
Si elabora l’oggetto
Si crea un nuovo oggetto Java che contiene dati
della risposta
Si trasforma l’oggetto Java in stringa JSON usando
il parser
Si trasmette la stringa JSON al client nel corpo
della risposta HTTP:
response.out.write(strJSON);
46
JSON e AJAX - 3
Sul lato client, all’atto della ricezione:
Si converte la stringa JSON in un oggetto
Javascript usando JSON.parse()
Si usa liberamente l’oggetto per gli scopi desiderati
47
Riassumendo
AJAX consente gestione asincrona
AJAX aggiunge un nuovo elemento al modello a eventi
L’uso di XmlHttpRequest rappresenta una modalità
alternativa per gestire gli eventi remoti
Abbiamo quindi:
Una modalità per gestire gli eventi a livello locale
Due modalità per gestire gli eventi remoti (postback
e XmlHttpRequest)
Si può adottare la tecnologia in modo più “radicale” e
utilizzare solo AJAX eliminando i caricamenti di pagina
(Single Page Applications --per esempio gmail)
Nei casi più comuni però AJAX e la modalità di
navigazione tradizionale convivono
48
Modello eventi a due livelli con AJAX
XmlHttpRequest Servlet
JavaScript
Postback
JSP
Risposta locale
Web
Server
DOM
Bean
49