martedì 6 novembre 2007

Tutorial Ajax - Capitolo 1

Capitolo 1 - La “Tecnologia” AJAX

Introduzione

Fino all’avvento della tecnologia AJAX, l’interazione tra client e server veniva effettuata in modo sincrono.

I dati presenti in un FORM venivano inviati tramite la funzione SUBMIT al web server, specificando con il metodo GET oppure POST la modalita’ con cui veniva effettuata la transazione e la trasmissione delle variabili – in chiaro oppure no – richiedendo l’esecuzione di una azione specifica da parte dell’application server in risposta a questa richiesta.

Solitamente si tratta dell’apertura di una pagina dinamica lato server (scritta di solito in JSP, PHP,o ASP) che si occupa del trattamento dei dati inviati, presenti nel form.

Questa pagina eventualmente effettua delle interazioni con un database server, e infine si occupa della creazione dell’output successivo che viene inviato dal webserver al browser dell’utente che aveva attivato l’operazione iniziale di Submit.

Successivamente il browser deve effettuare di nuovo il parsing – ovvero l’interpretazione del codice html e javascript ricevuto - , la costruzione del Document Object Model (DOM) in memoria e la visualizzazione della nuova pagina web come risultato finale di tutte queste operazioni.

Probabilmente non ci siamo nemmeno tanto preoccupati della fase di creazione del modello ad oggetti di rappresentazione della pagina che vogliamo visualizzare dentro il nostro browser, quello che viene detto Document Object Model, poiche’ raramente avremo avuto necessita’ di intervenire su di esso una volta creato.

Facciamo ora qualche considerazione su questo flusso di operazioni, puntando la nostra attenzione sull’efficienza complessiva.
Tutto il processo appena descritto – anche se per sommi capi - implica i seguenti punti critici di inefficienza:

- Nel caso di POST tutti gli stati attuali degli oggetti interni alla pagina contenente il form vengono inviati verso il web server remoto.
- il web server deve inviare una nuova pagina completa al browser come risultato delle operazioni di trattamento dei dati inviati.
- la pagina visualizzata sul browser viene “distrutta” quando si riceve la nuova pagina di risposta, e si ha di conseguenza la perdita dello stato di tutti gli oggetti che compongono la vecchia pagina nella memoria del browser, e la ricostruzione integrale del Document Object Model della nuova pagina da visualizzare.


Se abbiamo a che fare con il caricamento di una pagina totalmente diversa dalla precedente tutto cio’ e’ pressoche’ inevitabile.

E come vedremo sara’ cosi’ anche in Ajax.

Pero’ nel caso in cui viene modificato un unico dato di un form con diverse decine di elementi e dobbiamo ricaricare la stessa pagina aggiornata come conseguenza delle informazioni appena inserite, tipo il nostro esempio del CAP di una citta’ , tutta la pagina deve essere ricaricata completamente dal web server, perdipiu’ in modo sincrono.

Che significa in modo sincrono? Che l’utente non puo’ effettuare nessuna operazione sul form fintantoche’ non viene caricata la nuova versione aggiornata.

Per cui se il canale trasmissivo e’ congestionato, oppure stretto, o asimmetrico tra browser e web server, l’utente deve rimanere in attesa anche qualche secondo per poter continuare ad utilizzare il form in questione.

Se si trattasse di una applicazione desktop ci sarebbe gia’ un capannello di utenti pronti a farci la pelle se ci fossero questi tempo morti tra operazioni successive sullo stesso form!!!

Oltre a cio’ lo sviluppatore deve scontrarsi con il problema che le applicazioni web non riescono a mantenere lo stato degli oggetti interni come abbiamo visto prima.

Questo insieme di inefficienze era un aspetto imprescindibile nella costruzione delle interfacce grafiche “stateless” che hanno caratterizzato le applicazioni web fin dall’origine – per cui si parla comunemente di prima generazione di web applications, o Web 1.0.

Nel frattempo era avvenuta una innovazione che, come capita spesso con le innovazioni, non riscosse il meritato interesse.

Nel 2000 Microsoft sviluppa Outlook Web Access – OWA - , un prodotto per fornire una interfaccia web per il proprio Mail Server Outlook; OWA al suo interno contiene il componente ActiveX “XMLHTTP”.

Originariamente questo componente e’ stato scritto dal team di sviluppo di OWA, e successivamente venne incluso in Internet Explorer 5.0 e reso accessibile sul browser tramite vari linguaggi di scripting supportati da IE, tra cui Javascript, JScript e VBScript.
Il progetto Mozilla successivamente incorpora la prima implementazione nativa compatibile dell’oggetto XMLHttpRequest nel browser Mozilla 1.0 nel 2002. Successivamente seguita dalle implementazioni native nei browser Safari, Konqueror, Opera, Firefox e iCab.

Quindi vediamo che l’oggetto che sta alla base della nuova filosofia AJAX e’ presente in tutti i browser da molti anni. Questo componente permette agli script eseguiti sul browser di effettuare richieste HTTP in modo diretto senza passare dalla funzione Submit interna ad un form.

Nessuno pero’ aveva colto le potenzialita’ progettuali offerte da questo componente disponibile su tutti i browser. La ruota era stata inventata; restava da capire a cosa potesse servire e come poterla utilizzare!

Ma solo nel 2005, grazie ad un articolo di Jesse James Garrett – Ajax: A New Approach to Web Applications (
http://www.adaptivepath.com/publications/essays/archives/000385.php) si comincia a parlare di un nuovo approccio di progettazione delle web applications che fa uso di tecnologie esistenti, comunemente utilizzate, e che non richiedono l’aggiunta di plugin o componenti esterni aggiuntivi ai browser utilizzati.

La tecnica Ajax utilizza una combinazione di:

- HTML(o XHTML) e CSS (Cascading Style Sheets) per il markup e lo stile;

- DOM (Document Object Model) manipolato attraverso un linguaggio ECMAScript come JavaScript o JScript per mostrare le informazioni ed interagirvi;


- l'oggetto XMLHttpRequest per l'interscambio asincrono dei dati tra il browswer dell'utente e il web server. In alcuni framework Ajax e in certe situazioni, può essere usato un oggetto IFrame invece di XMLHttpRequest per scambiare i dati con il server e, in altre implementazioni, tag "script" aggiunti dinamicamente (JSON – Javascript Object Notation);

- in genere viene usato XML come formato di scambio dei dati, anche se di fatto qualunque formato può essere utilizzato, incluso testo semplice, HTML preformattato, JSON e perfino EBML. Questi file sono solitamente generati dinamicamente da script lato server.

Come il DHTML (o LAMP), Ajax non è una nuova tecnologia individuale, piuttosto è un gruppo di tecnologie utilizzate insieme.

Tutti I browser odierni possono utilizzare l’oggetto “XMLHttpRequest” che permette di effettuare richieste di carattere asincrono tra browser e webserver.

Mozilla Firefox ha questo componente direttamente disponibile – embedded nel codice del browser, mentre per Internet Explorer occorre caricare esplicitamente il componente ActiveX esterno “Microsoft.XMLHTTP”.

Come si fa a caricare il componente ActiveX XMLHTTP esterno?


Il codice Javascript seguente serve per il caricamento del componente activeX puo’ essere simile a questo:





Questo semplice codice associa alla variabile loadXHR il riferimento ad una funzione anonima che istanzia un oggetto HDR e vi associa il componente ActiveX Microsoft.XMLHTTP oppure l’oggetto nativo XMLHttpRequest( ) a seconda del browser (IE oppure Mozilla).

Internet Explorer, fino alla versione 6, non possiede l’oggetto nativo XMLHttpRequest, mentre Mozilla-Firefox e gli altri browsers non riescono a caricare gli oggetti ActiveX.

Per cui testando il caricamento degli oggetti ActiveX riusciamo a discriminare IE6 dagli altri browsers.

Se con IE non riesce a caricare il componente standard, si tenta di caricare una libreria alternativa – Msxml2. Se non riesce a caricare nemmeno questa seconda ritorna al chiamante un oggetto referenziato in modo “undefined”. Se invece abbiamo a che fare con un altro browser allora caricheremo, se disponibile, l’oggetto XMLHttpRequest nativo.


Dall’ ultima versione di Internet Explorer, la versione 7, si e’ reso nativo il componente, equiparando il tutto al caricamento dell’oggetto XMLHttpRequest.




In questo caso proviamo innanzitutto a caricare il componente nativo. Se cio’ non ha esito positivo (entriamo cioe’ nel ramo “catch”), probabilmente ci troviamo in un browser IE6 o precedente; percio’ tentiamo dapprima di caricare il componente ActiveX alternativo, che si suppone sia quello avanzato piu’ recente; se anche questo secondo tentativo non va a buon fine cerchiamo di caricare il componente primitivo come ultima possibilita’.


Dobbiamo vedere adesso quali funzionalita’ sono offerte dal componente appena caricato.

Prenderemo in esame il componente nativo, dato che quello piu’ datato e specifico per IE6- offre le stesse funzionalita’ differenziandosi solamente nel numero di stati collegati all’attributo readyState.

L’Oggetto XMLHttpRequest - XMLHTTP

Sia che si utilizzi l’oggetto nativo XMLHttpRequest che il controllo ActiveX Microsoft.XMLHTTP, si hanno a disposizione I seguenti metodi e i seguenti attributi:










MetodoDescrizione
abort() Cancella la richiesta in atto.
getAllResponseHeaders()Restituisce sotto forma di stringa tutti gli header HTTP
ricevuti dal server
getResponseHeader( nome_header ) Restituisce il valore dell'header HTTP specificato
open(metodo,URL )open(metodo,URL,async )open(metodo,URL,async,userName )open(metodo,URL,async,userName,password)Specifica il metodo, l'URL, and altri parametri opzionali
per la richiesta.
Il parametro metodo può assumere valore di
"GET", "POST", oppure "PUT" ("GET" è
utilizzato quando si richiedono dati, mentre "POST" è utilizzato
per inviare dati, specialmente se la lunghezza dei dati da trasmettere è
maggiore di 512 bytes).
Il parametro URL può essere sia relativo
che assoluto.
Il parametro "async" specifica se
la richiesta deve essere gestita in modo asincrono oppure no –
"true" significa che lo script può proseguire l'elaborazione senza
aspettare la risposta dopo il metodo send(), mentre "false"
significa che lo script è costretto ad aspettare una risposta dal server
prima di continuare.
send( content ) Invia la richiesta
setRequestHeader( chiave, valore)Aggiunge la coppia chiave/valore alla richiesta da
inviare.
onreadystatechangeGestore dell'evento lanciato ad ogni cambiamento di stato.
readyStateRestituisce lo stato corrente dell'istanza di XMLHttpRequest: 0 = non inizializzato, 1 = aperto, 2 = richiesta inviata, 3 = risposta in ricezione e 4 = risposta ricevuta.
statusTextRestituisce lo status in forma di stringa descrittiva (per esempio. "Not Found" oppure "OK").
responseTextRestituisce la risposta del server in formato stringa
responseXMLRestituisce la risposta del server come XML, che potrà essere analizzato e parsato come secondo le specifiche DOM del W3C.
statusRestituisce il codice HTTP restituito dal server (per esempio 404 per "Not Found" e 200 per "OK").


Perche’ AJAX?


Se consideriamo il termine nella sua accezione originaria esso e’ l’acronimo di “Asynchronous JAvascript and Xml”, che possiamo tradurre come “(utilizzo di) Javascript ed XML in modo asincrono”.

A come Asincrono


Il termine “asincrono” significa che lo script che utilizza l’oggetto XMLHttpRequest puo’ proseguire nell’elaborazione del codice successivo senza attendere il risultato atteso dopo il metodo send() fino a che sia reso effettivamente disponibile da parte del web server .

Ovvero, per chi conosce il meccanismo degli event handlers in Javascript, si definisce l’event handler associato all’evento onreadystatechange .

Quando l’engine javascript ricevera’ i dati dal web server verra’ richiamato l’event handler , eseguendolo non appena possibile, cioe’ appena terminata l’istruzione corrente che si trovava in esecuzione che probabilmente appartiene ad una diversa porzione del codice dello script, opure immediatamente se l’engine si trova in uno stato di inattivita’.

Per la precisione e’ possibile forzare l’oggetto per renderlo sincrono rispetto al resto dello script. In questo caso si interrompe l’esecuzione delle istruzioni successive al send() finche’ non si riceve la risposta da parte del web server.
Pero’ in questo modo non possiamo continuare ad eseguire altro codice nell’attesa, e se il web server non fornisce una risposta non possiamo riprendere l’esecuzione dello script.

Personalmente preferisco lasciare attivata l’impostazione asincrona, permettendo l’eventuale completamento dello script mentre si attendono i dati richiesti al server.


JA come JAvaScript

Se nel web 1.0 l’utilizzo del linguaggio Javascript era limitato a qualche riga di codice necessario a validare i campi di un form prima di inviare i dati al server, oppure a sviluppare qualche elemento visuale sul client come un menu ad albero (TreeMenu), nel nuovo approccio progettuale Javascript assume il ruolo principale per la creazione di un Engine global del client.

Nella sostanza, non avendo teoricamente piu’ la necessita’ di utilizzare gli oggetti Form e il loro meccanismo di Submit, potremmo non dover piu’ dismettere una pagina web e caricarne una nuova che contenga i dati aggiornati, ma caricare solo e soltanto i dati aggiornati e smistarli nella pagina web attuale.

Vedremo nel dettaglio quanta importanza assumera’ il linguaggio JavaScript nell’ambito della progettazione di una applicazione web Ajax.


- inizializzare la nostra applicazione caricando l’oggetto XMLHttpRequest
- intercettare le azioni effettuate dall’utente tramite l’interfaccia grafica
- identificare gli oggetti visuali coinvolti e gestire i valori associati ad essi
- gestire le condizioni per attivare l’evento send() , costruendo la richiesta che vogliamo effettuare in modo opportuno
- smistare i dati ricevuti in risposta dal serverIl linguaggio Javascript ora ci serve per:



Tutto cio’ e’ accompagnato dall’utilizzo delle strutture - funzioni di libreria ed attributi - rese disponibili all’interno del Document Object Model della pagina web . Percio’ alla base dell’utilizzo del javascript deve esserci una buona conoscenza del DOM creato da parte del browser all’atto del caricamento di una pagina web.



X come XML (eXtensible Markup Language)


Non preoccupatevi, l’utilizzo dell’xml non e’ obbligatorio. Gia’ vi sentivo: “va bene dover utilizzare javascript, un linguaggio ritenuto ostico, ma non anche l’xml...” .

Semplicemente Jesse James Garrett ha preso in considerazione l’xml come formato dei dati da ridistribuire all’interno di una pagina una volta che siano arrivati a fronte di una richiesta asincrona fatta al web server.

In realta’ oltre all’xml si puo’ utilizzare direttamente l’html oppure JSON (javascript Object Notation) come formato dei dati scambiati in modo asincrono. Il formato che preferisco per la flessibilita’ offerta e’ JSON, mentre l’HTML permette la massima velocita’ di ridistribuzione dei dati all’interno della pagina.

Personalmente non utilizzo l’XML, che secondo me comporta la scrittura di piu’ linee di codice e una maggiore lentezza per smistare i dati negli oggetti voluti.

Analizzeremo comunque successivamente le varie tecniche che possono essere utilizzate per formattare i dati scambiati tra client e server in modo asincrono secondo questi tre formati elencati, provando ad elencare pregi e difetti di ognuno secondo la mia personalissima esperienza.






Nessun commento: