I primi passi con Ajax

Introduzione

Questo tutorial ha il puro scopo di aprire le porte verso la costruzione di applicazioni dinamiche, veloci che sono alla base del Web 2.0, utilizzando Ajax (che si concretizza solitamente con l’utilizzo dell’oggetto XmlHttpRequest).
L’approccio che cercherò di utilizzare sarà il più semplice possibile in modo da far apprendere facilmente le basi che permetteranno poi al lettore di approfondire l’argomento leggendo le risorse che si trovano ormai ovunque su Internet.

Istanziamo l’oggetto XmlHttpRequest

Questo componente fu creato inizialmente dalla Microsoft (eh si dobbiamo ringraziarla :P) sottoforma di oggetto ActiveX per poi essere implementato (come oggetto nativo) pure da parte di Mozilla e Co.
Dobbiamo tenere conto di ciò nella fase di istanziazione dell’oggetto perchè il Javascript corrispondente per il browser Explorer sarà:

  1. var obj = new ActiveXObject("Microsoft.XMLHTTP");

mentre per ogni altro browser sarà:

  1. var obj = new XMLHttpRequest();

di conseguenza per permettere un’istanziazione “indipendente” dal browser basterà verificare l’esistenza dell’oggetto in questo modo:

  1. var obj;
  2. if (window.XMLHttpRequest) {
  3.     obj = new XMLHttpRequest();
  4. } else if (window.ActiveXObject) {
  5.     obj = new ActiveXObject("Microsoft.XMLHTTP");
  6. }

In realtà esistono altri script simili (più lunghi) che tengono conto delle varie implementazioni dei vari browsers web, ma la minestra è la stessa ;)

Analizziamo l’oggetto XmlHttpRequest

Una volta creato l’oggetto di riferimento abbiamo a disposizione una discreta quantità di metodi che elenco qui sotto:

  • abort(): Non fa altro che bloccare la richiesta corrente;
  • getAllResponseHeaders(): Ritorna il completo set degli headers come stringa (ad esempio il Cache-Control, ecc…);
  • getResponseHeader(<label>): Ritorna solo l’header corrispondente alla label;
  • open(<metodo>,url[,async[,<username>[,<password>]]])): Con questa funzione prepariamo la connessione indicando se utilizzare come metodo il POST, HEAD o GET ed impostando l’url con cui comunicheremo. Async ci permette di scegliere tra una comunicazione asincrona o meno (quindi decidere se l’utente deve aspettare che la comunicazione finisca per continuare ad interagire con la nostra applicazione); username e password servono per un’eventuale connessione sicura (non so fino a che punto sia sicura visto che username e password saranno visibili a chiunque legga il codice Javascript :P)
  • send(<contenuto>): Diamo il via alla nostra trasmissione dati :) Se facciamo un GET il contenuto è inutile (quindi o lo tralasciamo o lo settiamo come null) mentre per il POST dobbiamo riversare sul contenuto i dati da inviare (sottoforma di XML oppure URL Encoded)
  • setRequestHeader(<nome>,<valore>): Permette di modificare il valore ad un determinato header a nostra scelta (che verrà poi spedito mediante la nostra richiesta);

Eccovi un esempio di invio dati in GET:

  1. try {
  2.     obj.open("GET", "http://dominio.com/script.php?var1=uno&var2=due", true);
  3.     obj.onreadystatechange = onStateChange;
  4.     obj.send(null);
  5. } catch (e) {
  6.     alert("Errore: "+e);
  7. }

Come potete notare le variabili e in generale i dati da inviare allo script vengono inclusi nell’indirizzo come ormai siamo abituati a fare da anni (utilizzando il GET); a questo punto dopo aver impostato la funzione di callback possiamo inviare i nostri dati passando alcun parametro al metodo send().

Nel caso di un POST le cose cambiano leggermente:

  1. try {
  2.     obj.open("POST", "http://dominio.com/script.php", true);
  3.     obj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  4.     obj.onreadystatechange = onStateChange;
  5.     obj.send("var1=uno&var2=due");
  6. } catch (e) {
  7.     alert("Errore: "+e);
  8. }

Per eseguire la comunicazione in POST abbiamo dovuto inserire le variabili come contenuto del metodo send() e aggiungere una nuova intestazione che dicesse allo script che gli stiamo passando dei dati nella forma URL Encoded (altrimenti non funziona).
Mmm ho capito, ma che cos’è quella funzione di callback?

La funzione di callback (per l’esattezza un EventListener)

Prima di entrare nel cuore del discorso esaminiamo le proprietà dell’oggetto XmlHttpRequest:

  • readyState: Indica lo stato della comunicazione ritornando i possibili seguenti valori:
    • 0: Valore iniziale (stato indefinito);
    • 1: Metodo open() chiamato con successo;
    • 2: Metodo send() eseguito, la richiesta è stata inviata;
    • 3: Trasferimento dati in corso;
    • 4: Trasferimento completato;
  • responseText: Ritorno dei dati ricevuti dal server sottoforma di stringa;
  • responseXML: Ritorno dei dati ricevuti dal server sottoforma di XML;
  • status: Ritorna il codice di stato http, nel caso in cui la comunicazione è avvenuta con successo avremo il codice “200”;
  • statusText: Ritorna la descrizione relativa al codice di stato http attuale;

La proprietà che ci permette di gestire il trasferimento dei dati ed in generale i cambiamenti di stato è onreadystatechange.
Vediamone l’utilità con un esempio:

  1. function onStateChange() {  // Cambiamento Stato
  2.     if (obj.readyState == 4) { // Caricamento Avvenuto
  3.         if (obj.status == 200) { // con successo
  4.             // fai qualcosa
  5.         } else {
  6.             alert("Errore: "+obj.statusText);
  7.         }
  8.     }
  9. }

Negli esempi precedenti abbiamo indicato di chiamare ad ogni cambiamento di stato la funzione onStateChange che in questo caso ci permette di distinguere l’avvenuto caricamento da una situazione di errore.
Questo è l’utilizzo più comune del metodo ma le varie combinazioni di status e readyState ci permettono di poter gestire una miriade di casistiche.

Utilizziamo i dati ricevuti

Nell’esempio precedente ho messo un commento nel caso in cui la comunicazione sia avvenuta con successo ma è chiaro come in quella posizione debba andare il codice che cambia dinamicamente l’aspetto della pagina.
Un esempio è il seguente:

  1. document.getElementById("risultato").innerHTML=obj.responseText;

Con questa semplice riga di codice riversiamo i dati ricevuti nel tag corrispondente all’id “risultato”.

Conclusione

Dopo questa breve panoramica generale ho deciso pure di condividere una semplice applicazione Ajax che non fa altro che affidare ad uno script lato server (PHP) la somma di 2 numeri di 4 cifre.

Screenshot dell'applicazione Ajax di esempio

Ora non vi resta che lavorare! :P

Ajax: un nuovo approccio per le applicazioni Web

Incipit

Questo articolo è la traduzione della versione inglese intitolata “Ajax: A New Approach to Web Applications” scritta da Jesse James Garrett.

Introduzione

Qualsiasi progetto interattivo definito “affascinante” è destinato a diventare un’applicazione Web.
Dopo tutto, quando è stata l’ultima volta che abbiamo sentito qualcuno parlare di un progetto interattivo che non era presente sul Web? (Ok, oltre l’iPod.) Tutti i nuovi progetti innovativi sono destinati ad essere online.

Nonostante ciò, i progettisti web non possono fare altro che essere un po’ invidiosi dei colleghi che creano applicazioni Desktop.
Le applicazioni Desktop hanno una completezza e una velocità di risposta elevata che risultano essere fuori dalla portata del Web.
La semplicità che ha portato alla proliferazione del Web ha creato un divario tra le esperienze che noi possiamo fornire mediante le applicazioni Web e le applicazioni Desktop.

Quel divario oramai non esiste più. Basta dare uno sguardo a Google Suggest. Si può vedere come i termini suggeriti durante la digitazione vengano aggiornati quasi istantaneamente. Focalizziamoci su Google Maps. Ingrandiamo la mappa. Usiamo il cursore per trascinare e muovere la mappa. Ancora possiamo notare come qualsiasi cosa che accade è quasi istantanea, senza dover aspettare il ricaricamento della pagina.

Google Suggest e Google Maps sono due esempi del nuovo approccio alle applicazioni web che Adaptive Path chiama Ajax. Il nome è l’abbreviazione di Asynchronous JavaScript + XML e rappresenta una svolta fondamentale su ciò che sarà possibile fare sul Web.

Definiamo Ajax

Ajax non è una tecnologia. E’ l’insieme di più tecnologie indipendenti che insieme danno vita a potenti prospettive. Ajax incorpora a se:

Le classiche applicazioni Web lavorano in questo modo: molte delle operazioni non sono altro che una richiesta HTTP inoltrata al web server. Il server fa l’elaborazione – raccolta dati, manipolazione numeri, dialogo con eventuali sistemi legacy (datati) – e ritorna una pagina HTML al client. Questo è un modello adottato sin dalle origini del Web, considerato medium ipertestuale, ma come sanno i fanatici della User Experience, esso rende il Web ottimale per l’ipertesto ma non necessariamente così ottimale anche per le applicazioni software.

Modello tradizione applicazioni Web confrontato con quello Ajax
Figura 1: Il modello tradizionale delle applicazioni Web (alla sinistra) confrontato col modello Ajax (alla destra).

Questo approccio crea una miriade di soluzioni/quesiti tecnici che annebbiano quelli inerenti la User Experience. Mentre il server stà elaborando, l’utente cosa fa? Aspetta, e sarà costretto a farlo ad ogni richiesta.

Naturalmente, se noi progettavamo l’applicazione Web come un’applicazione software, questo non accadeva. Una volta che è stata caricata l’interfaccia, perchè l’interazione dell’utente deve fermarsi ogni volta che l’applicazione ha bisogno di processare il server? Perchè l’utente deve vedere l’applicazione dialogare con il server così pesantemente?

Ajax fa la differenza

Un’applicazione Ajax elimina la natura del Web ad essere contraddistinta da momenti alternati di dialogo-risposta che fanno attendere l’utente, introducendo un intermediario – un motore Ajax – tra l’utente e il server.
Può sembrare di aggiungere un livello all’applicazione che la rende meno veloce a rispondere, però è vero il contrario.

Invece di caricare una classica pagina web, ad inizio sessione, il browser carica il motore Ajax – scritto in Javascript e usualmente associato ad un frame invisibile. Questo motore è responsabile della comunicazione tra l’interfaccia utente e il server, mettendoli in comunicazione tra di loro. Il motore Ajax, indipendentemente dalla comunicazione con il server, permette all’interazione dell’utente con l’applicazione di essere asincrona. Così l’utente non è mai succube della finestra del browser bianca e dell’iconcina indicante il caricamento, aspettando che il server esegua le operazioni.

Modello di interazione sincrona confrontato con quella asincrona
Figura 2: Modello di interazione sincrona di un’applicazione web (sopra) confrontato con il modello asincrono Ajax (sotto).

Ogni azione dell’utente che normalmente genera una richiesta HTTP prende la forma di una chiamata Javascript verso il motore Ajax. Ogni risposta che non richiede la chiamata diretta al server – come validare alcuni dati, modificare dati in memoria – è un lavoro compiuto dal motore Ajax. Se il motore ha bisogno di interagire con il server per rispondere – invio dati da processare, caricare un interfaccia aggiuntiva, ricevere nuovi dati – il motore rende queste richieste asincrone, usualmente utilizzando XML, senza bloccare l’interazione tra utente e applicazione.

Chi usa Ajax

Google stà facendo molti investimenti nell’utilizzare AJAX come nuovo approccio. La maggior parte dei prodotti di Google introdotti anni fa – Orkut, Gmail, Google Groups, Google Suggest e Google Maps – sono applicazioni basate su Ajax. (per una migliore trattazione tecnica sull’implementazione Ajax, si consiglia di vedere l’analisi di Gmail, Google Suggest e Google Maps) Molti altri stanno seguendo lo stesso approccio: molte funzioni di Flickr sono basate su Ajax e il motore di ricerca di Amazon A9.com usa tecniche similari.

Questi progetti dimostrano che Ajax non risulta essere pura tecnica ma anche un’ottima pratica per la creazione di applicazioni molto utili. Non è una delle tante tecnologie utilizzate solo nei laboratori. Le applicazioni Ajax possono avere dimensioni diverse, dalla più semplice come Google Suggest, alla più complessa come Google Maps.

Uno sguardo al futuro

La maggiore sfida che Ajax pone davanti ai nostri occhi non riguarda la risoluzione dei problemi tecnici da esso derivati, ma il dimenticare tutte le limitazioni che riguardavano il Web, per lanciarsi verso la creazione di applicazioni robuste, veloci e sempre più simili alle applicazione Desktop.