Il 0% ha trovato utile questo documento (0 voti)
249 visualizzazioni20 pagine

Spaghetti Ajax: Guida Ajax in Italiano

Copyright
© Attribution Non-Commercial (BY-NC)
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
249 visualizzazioni20 pagine

Spaghetti Ajax: Guida Ajax in Italiano

Copyright
© Attribution Non-Commercial (BY-NC)
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

rss / comments / about / pages / it


Se ti interessano i temi di programmazione puoi iscriverti all'RSS del mio blog.

Spaghetti Ajax
Ovvero Ajax demistificato

di Salvatore antirez Sanfilippo, 9 Febbraio 2006 Aggiornato il 24 Ottobre 2006 con fix per IE7 Aggiornato il 30 Ottobre 2006 per eliminare un refuso, thx napyfab Aggiornato il 30 Maggio 2007, ora il codice finale memorizza l'oggeto della richiesta Ajax nella chiusura, in tal modo il codice gestisce richieste multiple senza problemi. consiglio a tutti di aggiornare il proprio codice alla nuova versione per contatti: antirez (at) gmail (dot) com

Licenza
Questo articolo coperto dalla seguente licenza Creative Commons: This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Italy License. Il codice sorgente Javascript e PHP sono coperti dalla licenza GPL version 2.0

Prologo
Quando ho pensato a questo articolo la mia idea fondamentale era quella di mostrare come passare dall'utilizzo di Ajax nudo e crudo, ad una forma pi astratta e potente. Mi sono accorto velocemente che un lettore ha bisogno di conoscere alcuni concetti di programmazione funzionale che i designer di Javascript hanno ben pensato di aggiungere al linguaggio per capire appieno come funzionano alcuni pezzi del codice che mostrer. Come conseguenza l'articolo ha assunto una nuova forma, quella di una guida veloce ma completa ad Ajax, dalle basi alle astrazioni che erano all'origine lo scopo dell'articolo. Molto del codice esposto viene utilizzato in un servizio di social bookmarking che sto sviluppando in questi mesi (segnalo.com), dunque le tecniche di programmazione mostrate sono reali, nel senso che sono applicabili a progetti in produzione.

Cos' Ajax
Se leggete in giro su internet forse vi farete l'idea che Ajax una cosa complicatissima che solo i programmatori pi bravi usano. In realt Ajax una stupidagine dal punto di vista tecnico, fondamentalmente l'unione di due cose. La capacit di Javascript di aggiornare parte di una pagina HTML senza che questa venga caricata nuovamente. La capacit di Javascript di fare richieste tramite il protocollo HTTP. Molto spesso si parla di Ajax anche quando soltanto una di queste due caratteristiche viene utilizzata, in ogni caso per capirci qualcosa iniziamo esplorando la prima capacit listata sopra: aggiornare le pagine in temo reale tramite Javascript.

Giocare con gli elementi di una pagina

http://antirez.com/articoli/spaghettiajax.html

Pagina 1 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

<script> function script1() { var e = document.getElementById("pluto"); e.innerHTML = "Benone!"; } </script> <div id="pluto"> Ciao come stai? </div> <input type="button" value="Esegui esempio" onClick="script1()" />

Esempio 1
Benone!
Esegui esempio

Provate a guardare il codice dell'esempio 1 e ad utilizzarlo (basta premere il bottone Esegui esempio). Alla pressione del bottone il contenuto dell'elemento DIV che ha come id pluto viene modificato da "Come stai" a "Benone!". Guardando il codice si capisce subito che farlo molto semplice, questa la funzione script1 che viene richiamata alla pressione del pulsante: function script1() { var e = document.getElementById("pluto"); e.innerHTML = "Benone!"; } La funzione script1 chiama la funzione document.getElementById passando come argomento l'identificativo del DIV, e quello che viene ritornato un riferimento all'oggetto che rappresenta il nostro DIV nella pagina HTML. L'oggetto in questione ha una propriet chiamata innerHTML che pu essere letta/scritta. Se viene letta restituisce il codice HTML presente dentro il DIV, se viene scrittta settandola a qualcosa di diverso come abbiamo fatto noi nell'ultima riga della funzione script1 il contenuto del DIV cambia e gli effetti si vedono immediatamente nella pagina. Facile no?

Javascript illusionista
Altra cosa molto utilizzata in applicazioni Ajax la possibilit di poter settare due propriet dello stile CSS di un oggetto chiamate visibility e display in modo da fare scomparire e apparire l'oggetto a piacimento. Bisogna far pratica anche con questo aspetto (altrettanto semplice) prima di scrivere applicazioni Ajax serie. Ecco il secondo esempio che illustra come fare a diventare prestigiatori in Javascript. <script> function script2() { var e = document.getElementById("pippo"); if (e.style.visibility == 'hidden') { e.style.visibility = 'visible'; e.style.display = 'block'; } else { e.style.visibility = 'hidden'; e.style.display = 'none'; } } </script> <div id="pippo"> Io scompaio e appaio! </div> <input type="button" value="Clicca per far sparire/ricomparire" onClick="script2()" />

http://antirez.com/articoli/spaghettiajax.html

Pagina 2 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

Esempio 2
Io scompaio e appaio!
Clicca per far sparire/ricomparire

Anche in questo caso l'idea di base non difficile da capire. Prendiamo il riferimento dell'oggetto con document.getElementById come al solito e modifichiamo lo stile dell'oggetto a nostro piacimento tamite oggetto.style.nomePropriet per fare quello che vogliamo. Qualcuno di voi che non conosce molto bene i CSS si chieder come mai modifichiamo sia la propriet visibility che display. La prima viene settata a visible se si vuole che l'oggetto sia visibile, mentre il valore di hidden la fa scomparire. La seconda invece viene settata a none quando si vuole che l'oggetto non prenda pi spazio nella pagina, altrimenti anche se invisibile occuperebbe lo spazio ugualmente. A volte ci desiderabile, altre volte non lo . Si noti come la propriet dispaly venga settata a block quando si vuole far ricomparire l'oggetto: questo valore infatti il default per un DIV ma varia al variare dei diversi elementi HTML, ad esempio per altri elementi il valore di default inline. Se volete saperne di pi cercate un buon tutorial sui CSS in giro. Congratulazioni! Sapete la met delle cose che bisogna sapere per utilizzare Ajax in maniera rudimentale. Dunque andiamo a scoprire l'altra met della storia.

Richieste HTTP da Javascript


Qual' la caratteristica principale di una applicazione in Ajax? Il fatto che la pagina si aggiorna senza la necessit di essere ricaricata, o al contrario che un evento generato dall'utente (come ad esempio la pressione di un tasto) causi una operazione sul server, senza la necessita di postare alcun FORM. Abbiamo visto come tramite Javascript sia possibile modificare il contenuto di una porzione della pagina, e di come gli elementi possano scomparire e ricomparire. Questo sufficiente per creare pagine i cui contenuti si aggiornano in maniera dinamica in linea teorica. In pratica per il sistema avere una utilit reale serve che ad una azione dell'utente vengano visualizzati dati che noi non potevamo avere gi in memoria. Immaginate un programma di gestione del magazzino scritto in Ajax. Quando l'utente digita il codice di una particolare merce immediatamente appare nella pagina la quantit ancora disponibile in magazzino. Ovviamente non pensabile che tutti i dati del magazino siano nella memoria di Javascript, dunque necessario eseguire una richiesta al server "di nascosto", e appena si ottiene la risposta necessaria aggiornare la pagina. Altro esempio, una web mail scritta in Ajax (chi non conosce Gmail?). Alla pressione del tasto Delete l'email viene cancellata. Eliminare la riga di quella email dalla lista delle email semplice, abbiamo gi visto come fare. Ma chi dice al server di cancellare l'email dal database se non possibile spedire un FORM? Quello che ci vuole per risolvere questi problemi la capacit di fare richieste al server in maniera asincrona, ovvero in background, senza che l'utente si accorga di niente. In questo modo Javascript pu contattare il server spedendo e ricevendo informazioni senza che la pagina venga ricaricata. Ma come si fa nella pratica?

L'oggetto XMLHttpRequest
Javascript capace di fare richieste HTTP in background sia utilizzando il metodo GET che il POST. Noi ci occuperemo solo del primo perch nella pratica quello che si utilizza di pi e una volta che conoscete questo, se vi fosse necessario, utilizzare l'altro non sar una cosa complicata. Per poter fare tale richiesta necessario utilizzare un oggetto che si chiama XMLHttpRequest in tutti i browser moderni escluso Internet Explorer che necessita di un diverso oggetto. Prima facciamo finta che Internet Explorer non esista (ho quasi l'impressione che il mondo riesca ad andare avanti lo stesso). Ci che serve per fare una richiesta HTTP in Ajax ovviamente un p di Javascript, e dall'altra parte (nel server) qualcuno che risponda alla richiesta, ovvero un piccolo script in PHP. Ovviamente l'applicazione server-side pu essere scritta in qualunque
http://antirez.com/articoli/spaghettiajax.html Pagina 3 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

linguaggio, tutti gli esempi di questo articolo sono scritti in PHP perch lo conosce anche mia zia Caterina, esperta di programmazione web e di uncinetto, a cui dedico questo articolo. La prima cosa che vi mostro la funzione che crea un oggetto XMLHttpRequest. function CreateXmlHttpReq(handler) { var xmlhttp = null; xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = handler; return xmlhttp; } Bisogna spiegare cosa fa questo codice. La funzione CreateXmlHttpReq prende in ingresso un solo argomento, una funzione, che verr chiamata quando la richiesta stata eseguita. Infatti Javascript un linguaggio che per l'input/output utilizza un modello basato sugli eventi, ricordate onClick, onChange, eccetera? L'idea che lui quando non sta fecendo niente per l'utente aspetta che si verifichi un evento associato ad una qualche funzione. Appena l'evento si verifica Javscript entra in azione chiamando l'handler (ovvero una funzione che gestisce l'evento) apposito. Bene, le richieste HTTP necessitano del tempo per essere eseguite, cosa dovrebbe fare Javascript nel mentre, aspettare? Non pu perch deve gestire il resto dell'applicazione. Dunque la richiesta viene lanciata in background. Appena ci sono novit di rilievo l'handler che noi passiamo come argomento a CreateXmlHttpReq viene chiamato per servire la nostra richiesta. Ora che sappiamo come creare l'oggetto necessario per fare una richiesta HTTP in background, e come associarvi un handler, ci serve sapere come utilizzarlo per richiamare una data pagina e qualche altro dettaglio. var myRequest = CreateXmlHttpReq(myHandler); myRequest.open("GET","primo.php"); myRequest.send(null); Come potete immaginare il codice sopra setta l'oggetto XMLHttpRequest in maniera da fargli eseguire una query tramite il metodo GET al file primo.php, e nella riga immediatamente successiva spedisce la richiesta. A questo punto la richiesta parte... ma non abbiamo ancora scritto la funzione myHandler che deve occuparsi di gestirla quando ci sono novit in vista. function myHandler() { if (myRequest.readyState == 4 && myRequest.status == 200) { alert(myRequest.responseText); } } Si noti come myRequest sia una variabile globale, infatti l'handler viene chiamato senza arogmenti, non c' nessuno che gli comunica a quale oggetto si riferisce la richiesta per cui stato invocato, dunque bisogna avere un riferimento globale all'oggetto XMLHttpRequest. Nel codice finale che viene presentato in questo articolo l'oggetto viene invece registrato nella chiusura (se leggete di piu' capirete cos'e'), cio' permette di gestire in maniera affidabile piu' richieste concorrenti. Ma per ora non ci pensate, facciamo finta che il modo migliore sia avere una variabile globale per l'oggetto XMLHttpRequest. Il nostro handler viene invocato pi volte durante una richiesta HTTP. La propriet readyState ci dice per quale motivo l'handler stato chiamato in base al valore che assume. 0: 1: 2: 3: 4: uninitialized loading loaded interactive complete

Ci che a noi interessa fare qualcosa quando la richiesta viene completata, per questo testiamo che readyState abbia il valore 4. A quel punto sar settata anche la propriet status che contiene il

http://antirez.com/articoli/spaghettiajax.html

Pagina 4 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

valore dello stato della risposta HTTP, che 200 per richieste avvenute con successo, il famoso 401 per pagine non trovate, e cos via. Come averete visto il nostro handler una funzione che si milita a visualizzare un alert. Ora mettiamo le parti assieme e proviamo questo esempio, manca per solo una parte: il file PHP. Ecco dunque il sorgente di primo.php: var <? myRequest = null; echo("Questi dati vengono dal PHP"); function CreateXmlHttpReq(handler) { ?> var xmlhttp = null; xmlhttp = new XMLHttpRequest(); Ecco l'esempio con il codice completo handler; xmlhttp.onreadystatechange = e la possibilit di vederne gli effetti dal vivo. return xmlhttp; } function myHandler() { if (myRequest.readyState == 4 && myRequest.status == 200) { alert(myRequest.responseText); } } function esempio3() { myRequest = CreateXmlHttpReq(myHandler); myRequest.open("GET","primo.php"); myRequest.send(null); } </script> <input type="button" value="Clicca per lanciare la richiesta" onClick="esempio3()" /> Nota: questo script non funziona con Internet Explorer!
Clicca per lanciare la richiesta

Ogni volta che cliccate sul bottone Clicca per lanciare la richiesta, tale richiesta parte, quando la risposta del server disponibile l'handler viene richiamato con la giusta combinazione di readyState e status e l'alert col contenuto della risposta viene visualizzato. Se avessimo voluto avremmo potuto mettere un DIV nella pagina e tramite la propriet innerHTML sarebbe stato possibile mostrare il risultato della richiesta aggiornando il DIV direttamente, invece che utilizzare un alert. Questo un buon esercizio che vi consiglio di fare subito prima di continuare a leggere l'articolo. Tra poco affronteremo argomenti un tantino pi complicati dunque consigliabile giocare un p con i concetti esposti fino a questo punto per acquisire dimetichezza.

Internet Explorer comunque esiste


E non lo possiamo ignorare poich pi o meno l'ottanta percento delle persone lo utilizza. Per fortuna non serve modificare che una singola funzione per rendere il nostro codice compatibile con IE, la CreateXmlHttpReq2. Ecco la versione compatibile: // Create the XML HTTP request object. We try to be // more cross-browser as possible. function CreateXmlHttpReq2(handler) { var xmlhttp = null; try { xmlhttp = new XMLHttpRequest(); } catch(e) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } } xmlhttp.onreadystatechange = handler; return xmlhttp; } Questa funzione tenta di risolvere un certo numero di problemi con diverse versioni di Internet Explorer, e un problema con una vecchia versione del browser Mozilla. Come potete vedere il modo in cui

http://antirez.com/articoli/spaghettiajax.html

Pagina 5 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

viene creato l'oggetto per la richiesta HTTP e il modo in cui viene settato l'handler variano nei diversi browser, ma gli oggetti sono molto simili e l'handler non deve essere modificato per gestire l'uno o l'altro. Ci importantissimo: abbiamo isolato il codice non compatibile tra i diversi browser in un'unica funzione! C' un secondo problema con IE in realt, fa il caching delle richieste HTTP fatte in questo modo, dunque se sono effettuate utilizzando la stessa URL pi volte, anche se lo script PHP richiamato produce diversi risultati, il risultato ottenuto sar sempre lo stesso. Per evitare questo problema invece di richiedere qualcosa come script.php basta richiedere script.php?rand=numeroCasualie. In questo modo inganniamo IE facendogli credere che ogni volta si tratta di una richiesta diversa ed evitiamo il problema della cache. Per generare un numero casuale in Javascript si utilizza la funzione Math.random, dunque per evitare il problema della cache di IE tutto quello che dovremmo modificare nello script di sopra la riga in cui la richiesta viene settata utilizzando il metodo open. Nello script originale usavamo: myRequest.open("GET","primo.php"); Mentre sarebbe opportuno utilizzare: myRequest.open("GET","primo.php&rand="+escape(Math.random()));

Un esempio completo che funziona su tutti i browser


A questo punto siamo pronti per riscrivere l'esempio di sopra con alcune modifiche. Per prima cosa utilizzeremo la funzione CreateXmlHttpReq2 compatibile con IE, secondo utilizzeremo il parametro casuale nella richiesta per evitare la cache e terzo modificheremo lo script PHP in modo da ritornare il tempo in secondi, cos possiamo vedere che i dati cambiano ad ogni invio. Infine questa volta useremo un DIV per visualizzare il risultato dinamicamente utilizzando innerHTML. Il codice integrale il seguente. var myRequest = null; function CreateXmlHttpReq2(handler) { var xmlhttp = null; try { xmlhttp = new XMLHttpRequest(); } catch(e) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } } xmlhttp.onreadystatechange = handler; return xmlhttp; } function myHandler2() { if (myRequest.readyState == 4 && myRequest.status == 200) { e document.getElementById("ex4result"); Il PHP del file=secondo.php il seguente semplice script: e.innerHTML = myRequest.responseText; } <? } if (isset($_GET['nome'])) { $n = esempio4() { function strtolower($_GET['nome']); $name['giorgio'] = "Bianchi"; var nome = document.f1.nome.value; $name['vittorio'] = "Rossi"; var r = Math.random(); $name['augusto'] = "Verdi"; myRequest = CreateXmlHttpReq(myHandler2); if (isset($name[$n])) { myRequest.open("GET","secondo.php? echo("Il cognome di $n $name[$n]"); nome="+escape(nome)+"&rand="+escape(r)); } else { myRequest.send(null); echo("Non conosco il cognome di $n"); } } echo(" tempo corrente in secondi: ".time().""); } ?>

http://antirez.com/articoli/spaghettiajax.html

Pagina 6 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

Nome: Risultato:

Visualizza cognome

Per testare l'esempio sopra provate a immettere i nomi Giorgio, Vittorio, Augusto e premere Visualizza congome, poi provate a mettere un altro nome che non contenuto nell'array del programma secondo.php, ad esempio Alessio. Avete capito bene come funziona il codice? Complimenti, ora potete dire di sapere come funziona Ajax, e anche spargere la voce sul fatto che le basi sono molto semplici. Ma non illudetevi, Ajax facile, chiunque pu imparare ad usarlo. Quasi tutta la programmazione cos, alla portata di tutti. La differenza che potete fare voi che se avete talento e voglia potete diventare dei grandi programmatori, capaci di utilizzare astrazioni pi potenti che vi rendono il lavoro pi facile e veloce. La seconda parte di questo articolo, che la motivazione per cui la prima parte stata scritta, si sofferma proprio su questo: l'astrazione, ma prima permettetemi una breve digressione su XML.

XML? no, grazie


Il termine Ajax un acronimo, e significa: Asynchronous Javascript and XML XML una delle tre parti, eppure noi abbiamo utilizzato Ajax fino ad ora senza neppure toccare XML. Come mai? semplicemente chi ha coniato il termine pensava che il modo migliore per comunicare tra il programma che risiede sul server, e il client che fa la richiesta in Ajax, era quello di utilizzare XML. Lo pensano in molti, ma in realt Ajax non ha niente a che fare con XML. PHP (o chi per lui) e Javascript possono spedirsi i dati in qualunque formato desiderabile. Si noti come di solito la grande quantit dei dati passi dal server al client. Ad esempio in Gmail il server spedisce al client informazioni sui messaggi, e il client si occupa tramite Javascript di visualizzare tali messaggi nella pagina dell'utente. Di solito il passaggio di parametri dal client al server avviene semplicemente passando dei parametri tramite una richeista GET, come abbiamo fatto noi poco fa nel caso del nome. Per questa ragione uno dei miei metodi preferiti per passare dati dal server all'interprete Javascript del client utilizzare un formato di semplice testo nel caso di operazioni molto semplici. Ad esempio se devo controllare se uno username in fase di registrazione in un servizio web gi occupato prima di ricaricare la pagina, faccio ritornare dal server un semplice OK o ERR, e controllo dal Javascript se la stringa ritornata l'una o l'altra. Se invece necessario passare molti dati, utilizzo una tecnica diversa. Creo nello script che gira sul server un array Javascript e lo spedisco. Dal lato Javascript uso la funzione eval per valutare l'Array, gi pronta, non mi serve scrivere un parser. Ecco un esempio in PHP. <? echo('var data = Array("'); echo($a); echo('","'); echo($b); echo(")"); ?> Semplice no? ma cosa succede se $a o $b contengono caratteri (in questo contesto) speciali come le virgolette? Per evitare qualunque problema basta utilizzare la seguente funzione. <? function safejsstring($s) { $a = unpack("C*",$s); $res = ""; foreach($a as $byte) { $res .= sprintf("\\x%02x", $byte); } return $res;
http://antirez.com/articoli/spaghettiajax.html Pagina 7 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

} ?> Tale funzione prende una stringa PHP e la converte interamente in sequenze di escape nella forma \xHH dove HH sono due cifre esadecimali. In questo modo Javascript riuscir sempre ad interpretare la stringa in maniera corretta anche se fosse costituita da dati binari. Dal PHP potete generare semplicemente anche Array annidati, in breve strutture dati complicate quanto lo desiderate. Se volete usare XML... non vi tiene nessuno ;) ma volevo soltanto che fosse chiaro che non necessario e il termine finito dentro questa tecnica di programmazione solo perch l'autore dell'acronimo ha deciso cos.

Parte seconda: facciamo di meglio


Carino Ajax vero? Ma se pensate a quanto codice abbiamo scritto per fare una mezza richiesta HTTP in Javascript, che abbiamo utilizzato in maniera esplicita una variabile globale, e quanto poco astratto dal reale problema che risolve risulta il nostro codice, non c' mica da essere orgogliosi... dobbiamo proprio correre ai ripari. Benvenuti nella seconda parte di questo articolo, dove (se non lo sapete gi), imparerete come innalzare il livello del vostro Javascript utilizzando i concetti della Programmazione Funzionale. Se non sapete di cosa si tratta vi consiglio di leggere questa parte anche se non siete interessati a sapere di pi su Ajax. In ogni caso i concetti che seguono sono assolutamente necessari per seguire la parte pi avanzata dell'articolo, in cui saranno usati per creare una piccola libreria Ajax che ci libera dal tedio di fare tutto a mano, e che sembra integrata nel linguaggio.

Funzioni anonime
Utilizzando linguaggi che sono fondamentalmente imperativi, come il C, Java, PHP, Javascript (anche se l'ultimo come vedremo ha un buon supporto per la programmazione funzionale), una delle cose che capita spesso di fare quella di scorrere un array indice dopo indice tramite un ciclo for. Partiamo da un esempio reale... una operazione spesso necessaria , dato un array, prendere l'elemento col valore massimo. Serve per un sacco di cose, una tra tutte: avete presente la nuova moda web 2.0, di visualizzare dei tag con un font o con un colore proporzionale alla sua popolarit? (pi spesso proporzionalmente al logaritmo della popolarit). Bene, la prima cosa che serve per fare la proporzione ovviamente sapere qual' il valore del massimo elemento. In javascript scrivereste abbastanza ovviamente: var a = Array(10,5,7,81,28); var max = a[0]; for (i = 1; i < a.length; i++) { if (a[i] > max) { max = a[i]; } }

La fuzione reduce
E se vi serve sapere qual' la stringa pi lunga di un array? Vi serve un altro ciclo for. Una volta un programmatore ha detto Se per ogni ciclo for che ho scritto nella mia vita potessi ricevere un centesimo sarei ricco. Come possiamo liberarci da questa schiavit del ciclo for? La soluzione data dal fatto che in Javascript le funzioni sono oggetti di prima classe, che in breve significa che le funzioni cos come un oggetto stringa o un numero possono essere passate come argometi ad altre funzioni e ritornate come valore di ritorno da funzioni. In pratica non c' differenza sostanziale tra quello che si pu fare con un numero, con una stringa e con una funzione. Ora abbiamo la soluzione al nostro primo problema, possiamo scrivere una potente funzione che si chiama reduce. function reduce(a,f) {
http://antirez.com/articoli/spaghettiajax.html Pagina 8 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

if (a.length == 0) { throw emptyArrayError; } var res = a[0]; for (var j = 1; j < a.length; j++) { res = f(res,a[j]); } return res; } Questa piccola funzione prende in ingresso due oggetti: il primo un array, il secondo una funzione f. Applica f ai primi due elementi dell'array, e prende il risultato. Poi applica f al risultato e al terzo elemento dell'array, e cos via. in pratica se L'array contiene i valori 1,2,3,4 il risultato di reduce f(f(f(1,2),3),4). Come vedete la funzione f che viene passata a reduce prende in input due argomenti, li compara, e ritorna uno dei due. Se f fosse una funzione che dati due argomenti ritorna il pi grande dei due, il risultato di reduce(a,f) sarebbe il massimo elemento dell'array! Bene, ora siamo in grado di scrivere del codice che prende l'elemento pi grande di un array senza ricorrere ad un clico for usando reduce. Ecco come. function max(a,b) { if (a > b) return a; else return b; } var a = Array(10,5,7,81,28); var max = reduce(a,max); In pratica abbiamo estrapolato quello che c' di uguale in molti cicli for e lo abbiamo separato dal resto del codice, incarnandolo nella funzione reduce. Rimane un problema, abbiamo dovuto scrivere la funzione max, e ci pu essere noioso. Ora che abbiamo reduce vorremmo utilizzarla in tanti piccoli contesti quotidiani, e scrivere continuamente funzioni aiutanti una noia. Ma Javascript non un linguaggio smidollato! Infatti ha un concetto molto utile, le funzioni anonime. Se in Javascript le funzioni sono oggetti come tutti gli altri, perch devono avere per forza un nome? Una stringa non ha un nome, neppure un numero. Anche le funzioni possono non averlo, possono essere scritte in maniera "letterale", o messe dentro una variabile, come tutti gli altri tipi di dato. Basta usare la seguente notazione. var a = Array(10,5,7,81,28); var maxfunction = function(a,b) { return (a>b) ? a : b }; var max = reduce(a,maxfunction); Cos come Array(1,2,3) ritorna un array, function(parametri) {codice} ritorna una funzione. Dunque nell'esempio sopra abbiamo creato una funzione e abbiamo messo il suo riferimento in una variabile, e poi l'abbiamo usata come argomento di reduce. Ma perch usare una variabile intermedia? Ecco dunque la versione finale, in tutto il suo splendore ;) var a = Array(10,5,7,81,28); var max = reduce(a,function(a,b){return (a>b)?a:b;}); Confrontate questo codice per trovare il massimo elemento di un array con quello che avevamo scritto utilizzando il ciclo for all'inizio. Non solo questo, reduce fa tutto quello che volete... avete voglia di sommare l'array? Bene: var a = Array(10,5,7,81,28); var sum = reduce(a,function(a,b){return a+b;}); Il limite la vostra fantasia.

Le amiche di reduce: map e filter


Anche se per i nostri scopi la cosa importante la comprensione delle funzioni anonime (che permetteranno di capire cosa sono le
http://antirez.com/articoli/spaghettiajax.html Pagina 9 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

chiusure nel prossimo paragrafo), la programmazione funzionale uno strumento potentissimo, dunque illustro brevemente altre due classiche primitive della programmazione funzionale, map e filter. Come reduce anche map prende come input un array e una funzione f, ma invece che ridurre l'array ad un solo elemento applicando una funzione come fa reduce, map ritorna un nuovo array in cui ogni elemento stato ottenuto trasformando il vecchio elemento nel nuovo tramite una funzione f. In termini pratici, dato l'array 1,2,4,7 ci che ritorna map(a,f) f(1),f(2),f(4),f(7). Ecco la funzione map. function map(a,f) { var res = Array(); for (var j = 0; j < a.length; j++) { res[j] = f(a[j]); } return res; } Questa volta la funzione f che passiamo come argomento a map una funzione che prende un solo argomento (una funzione unaria), e ritorna un valore. Ecco un esempio di applicazione di map, che non fa altro che trasformare un array di numeri in un array dei quadrati di tali numeri. var a = Array(1,5,4,3); var b = map(a,function(x){return x*x}); Alla fine del programma l'array b conterr gli elementi 1,25,16,9. Come potete immaginare possibile sommare gli effetti di map e reduce, ad esempio provate a scrivere il codice che utilizzando queste due primitive sommi i quadrati degli elementi di un array. Si noti come anche se teoricamente siamo interessati soltanto al valore di ritorno della funzione f, sia possible forzare map a lavorare come una sorta di foreach. var a = Array(1,5,4,3); map(a,alert); Queste due righe di codice avranno l'effetto di fare l'alert di tutti gli elementi dell'array. Il risultato della funzione map non viene utilizzato in nessun modo perch&egrabe; non nostro scopo, in questo caso siamo solo interessati nell'effetto collaterale (o side effect) che ha la chiamata della funzione f (ovvero alert), che quello di visualizzare i numeri. L'ultima delle funzioni che giocano un ruolo importante tra le primitive della programmazione funzionale su cui ci soffermeremo filter. Questa funzione sar solo descritta in quanto concettualmente molto simile alle altre due. L'implementazione di filter lasciata come esercizio al lettore. Ma cosa fa filter? Dato un Array e una funzione unaria f in ingresso, ritorna un Array composto solo dagli elementi per cui la chiamata alla funzione f restituisce true. In pratica filter filtra l'array e ne crea uno che ha come elementi solo quelli che piacciono alla funzione passata come argomento, che utilizza il valore di ritorno true o false per indicare se tenere o scartare ogni dato elemento Utilizzando assieme map, filter e reduce per esempio possibile in una singola linea di codice processare un array per tenere solo gli elementi che sono maggiori di 10, elevarli al quadrato e ottenerne la somma. Ma ora tempo di chiudere questa (spero interessante) parentesi e continuare il nostro breve incontro delle caratteristiche evolute di Javascript.

Le chiusure
La pi semplice definizione di chiusura, e anche una delle meno immediatamente comprensibili per chi non le conosce, la seguente: una chiusura una funzione con uno stato ad essa associato. Cosa significa di preciso? Per spiegarlo bisogna fare un passo indietro, e ritornare alle funzioni anonime di cui abbiamo parlato prima (se non ricordate bene cosa sono, tornate indietro a fare un ripasso e poi

http://antirez.com/articoli/spaghettiajax.html

Pagina 10 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

ritornate qui!). Abbiamo detto che in Javascript le funzioni sono un oggetto di prima classe, e abbiamo infatti visto come sia possibile passare una funzione come argomento ad un'altra funzione. Abbiamo anche affermato che possibile scrivere funzioni che ritornano funzioni come argomento. Ad esempio il codice function creaFunzione() { var f = function() {return 1}; return f; } var b = creaFunzione(); alert(b()); quando viene eseguito mostra un alert in cui c' scritto 1. La funzione creaFunzione ritorna una funzione che non fa altro che ritornare 1 (scusate il gioco di parole, ma proprio cosi, creaFunzione ritorna una funzione che quando viene chiamata ha come valore di ritorno l'intero 1). Tale funzione ritornata da creaFunzione viene salvata dentro la variabile b. Da questo momento in poi b pu essere usata come una funzione, infatti la chiamiamo nell'ultima riga del programma di esempio, per ottenere l'argomento di alert. Fin qui nulla di nuovo. Esistono le funzioni anonime, e come tutte le altre funzioni sono oggetti di prima classe: possono essere utilizzato come argomento, ritornate da altre funzioni, tenute dentro le variabili, e qualunque altra cosa fareste con un numero, una stringa o un array (anch'essi tutti oggetti di prima classe). Ma cosa accade se nel corpo di una funzione anonima c' un riferimento ad una variabile che definita al momento della sua creazione nello scopo esterno ad essa? Un esempio chiarir cosa voglio dire. function creaFunzione(valore) { var f = function() {return valore}; return f; } La variabile valore esiste mentre la funzione creaFunzione viene eseguita, e come potete vedere compare nel corpo della funzione anonima che alla fine restituiamo come valore di ritorno. Ma quando utilizzeremo la funzione anonima creata, creaFunzione non sar pi attiva, dunque cosa contiene la variabile valore quando la funzione anonima viene invocata?. Concentratevi che questo un passaggio delicato. Ci che accade che la funzione anomina create ricorder il riferimento all'oggetto che aveva la variabile valore al momento in cui la funzione anonima stata creata. Dunque se scrivo a = creaFunzione(10); b = creaFunzione(20); a(); // ritorna 10 b(); // ritorna 20 Le funzioni a e b ritorneranno ad ogni chiamata rispettivamente 10 e 20! Ecco cosa significa che una chiusura una funzione con uno stato ad essa associato. La chiusura ricorda tutti i riferimenti a variabili esterne al momento della sua creazione. La cosa interessante che questo stato che la chiusura si porta appresso pu anche essere modificato. Per esempio possibile scrivere una funzione che ritorna delle funzioni che contano. function creaContatore() { var c=0; return function() { return c++; } } var a = var b = a(); /* a(); /* a(); /* b(); /* b(); /* creaContatore(); creaContatore(); ritorna 0 */ ritorna 1 */ ritorna 2 */ ritorna 0 */ ritorna 1 */

http://antirez.com/articoli/spaghettiajax.html

Pagina 11 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

a(); /* ritorna 3 */ Ad ogni chiamata a() e b() ritornano l'intero successivo (partendo da zero), e ricordano dove erano arrivate. Siccome questo non un corso completo di programmazione funzionale non mi posso spingere oltre, ma provate a immaginare le possibilit... (argh, sembra lo spot della Apple).

Chiusure e handler?
C' un campo in cui necessario soffermarsi sull'applicazione delle chiusure: le funzioni che gestiscono eventi in Javascript, ovvero i cos detti handler. Partiamo da un problema reale, e vediamo come viene affrontato tramite le chiusure. In una pagina HTML ci sono due elementi: uno spazio in cui l'utente pu scrivere qualcosa (un banale elemento INPUT di tipo text) e un bottone. Alla pressione del bottone Javascript fa partire un timer, che dopo dieci secondi mostrer un alert che visualizza cosa c'era scritto nell'INPUT al momento in cui l'utente aveva premuto il tasto. Eccovi l'esempio funzionante.
Premi qui

L'utete potrebbe ad esempio scrivere hello e premere il tasto, poi scrivere world e premere il tasto. Dopo alcuni secondi vedrebbe in successione due alert, uno in cui scritto hello e l'altro in cui scritto world. Per implementare un tale programma qualcuno potrebbe essere tentato di scrivere qualcosa come: function whenButtonIsPressed() { setTimeout(showAlert, 10000); } function showAlert() { var e = object.getElementById("inputobj"); alert(e.value); } Nell'esempio immaginiamo che il bottone abbia un evento onClick che richiama la funzione whenButtonIsPressed e che il testo digitato dall'utente sia contenuto in un elemento INPUT con ID inputobj. Ovviamente il codice mostrato sopra non funziona, perch l'handler del timer, ovvero la funzione showAlert, va a leggere il contenuto dell'INPUT solo quando deve visualizzare l'alert. Se nel mentre il contenuto cambiato perch l'utente nel corso dei 10 secondi ha scritto qualcosa di nuovo il nostro gioco non funziona. Noi vogliamo che alla pressione del tasto, l'alert risultante 10 secondi dopo visualizzi quello che c'era scritto quando il tasto era stato premuto. Ci servirebbe un handler che ha memoria del passato... ovvero, una chiusura! Ecco il codice corretto: function whenButtonIsPressed() { var string = document.getElementById("inputobj").value; var myHandler = function() { alert(string); }; setTimeout(myHandler, 10000); } Abbiamo risolto il problema con un'unica funzione. La chiusura che usiamo come handler ha un riferimento a string, dunque si crea un collegamento tra l'oggetto che conteneva tale variabile al momento della creazione della funzione e la funzione stessa. Nota: questo particolare problema potrebbe essere risolto anche tramite eval(), ma ci sono molti casi in cui le chiusure risolvono problemi non risolvibili con eval() e tantissimi altri casi in cui risolvono i problemi in maniera molto pi elegante.

Ajax comodo
Siamo prossimi alla conclusione. Con le conoscenze acquisite ci proponiamo di scrivere delle funzioni che rendono Ajax cos semplice

http://antirez.com/articoli/spaghettiajax.html

Pagina 12 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

che per fare una query in Ajax e mostrare la risposta in un alert baster scrivere: ajaxGet("primo.php",myHanlder); function myHandler(content) { alert(content); } In pratica la funzione ajaxGet dovr predisporre la query, e poi chiamare l'handler passando come primo argomento il risultato della richiesta HTTP solo se la richiesta andata a buon fine. Non c' nessuna variabile globale, nessun controllo dello stato, tanto meno la ripetizione del codice necessario per creare l'oggetto necessario alla richiesta e alla sua inizializzazione. Ma non ci accontentiamo di questo, l'altra importantissima caratteristica che deve avere la nostra nuova interfaccia verso Ajax la seguente: qualunque argomento addizionale passato alla funzione ajaxGet dovr essere passato all'handler quando la richiesta viene completata, dunque il codice: ajaxGet("primo.php",myHandler,"a",10); function myHandler(content,first,second) { alert(content); alert(first); alert(second); } Avr l'effetto di eseguire la richiesta e chiamare l'Handler con la risposta ottenuta dal server come primo argomento, la stringa "a" come secondo argomento e l'intero 10 come terzo. Riflettete un p su questa caratteristica e vi accorgerete come ora la richiesta sia in grado di portarsi appresso lo stato, e permetta dunque di usare lo stesso handler per gestire diverse situazioni. Infatti dietro l'implementazione di ajaxGet ci sono proprio le chiusure, abbiamo preso i vantaggi della closure e li abbiamo trasportati nella nostra API, anche se nella pratica per usare tale API non serve conoscere le chiusure. E' importante notare come la possibilit di passare argomenti addizionali all'handler aumenti la potenza della nostra interfaccia. Immaginate di avere due divesi elementi DIV nella pagina. Volete fare delle richieste a diversi file PHP e visualizzare il contenuto in un DIV o nell'altro tramite innerHTML. Potete semplicemente scrivere: ajaxGet("primo.php",myHandler,"primodiv"); function myHandler(content,elementid) { var e = document.getElementById(elementid); e.innerHTML = content; } Se pi tardi volete fare una nuova richiesta ma visualizzare il risultato in un DIV diverso, potrete riutilizzare il vecchio handler e scrivere semplicemente: ajaxGet("primo.php",myHandler,"secondodiv"); Vedrete come nella vita reale qualunque applicazione Ajax non banale presenta questo tipo di necessit. Ora che abbiamo visto come vorremmo che fosse la nostra interfaccia verso Ajax, andiamo ad implementarla utilizzando le tecniche di programmazione imparate fino ad ora e qualcuna nuova che sar esposta quando occorre.

Implementazione
Iniziamo dalla fine, mostrando il codice completo della funzione ajaxGet e della sua funzione aiutante ajaxOk. var ajax_req = null; function ajaxOk() { if (ajax_req.readyState == 4 && ajax_req.status == 200) { return ajax_req.responseText; } else { return false; } }

http://antirez.com/articoli/spaghettiajax.html

Pagina 13 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

function ajaxGet(url,handler) { var a = new Array("placeholder"); for (var j=2; j<arguments.length; j++) { a[a.length] = arguments[j]; } var myhandler = function() { var content = ajaxOk(); if (content != false) { a[0] = content; return handler.apply(this, a); } } ajax_req = CreateXmlHttpReq(myhandler); ajax_req.open("GET",url); ajax_req.send(null); } La funzione ajaxOk svolge un compito banale, se avete ancora fresca nella memoria la prima parte dell'articolo ricorderete che le propriet readyState e status dell'oggetto xmlHttpReq vengono utilizzate per controllare lo stato della richiesta, ovvero se andata a buon fine. In caso positivo, tramite la propriet responseText si pu ottenere il contenuto della riposta HTTP. Alla luce di questi fatti si vede subito che ajaxOk non fa altro che controllare se la richiesta registrata nella variabile globale ajax_req sia terminata con esito positivo, e in tal caso ritornare la risposta ottenuta. In caso contrario invece viene ritornato false. Analizziamo ora il pezzo forte, ovvero ajaxGet. Questa una funzione che utilizza un numero variabile di argomenti. In Javascript ogni funzione ha accesso esplicito alla lista di argomenti con cui stata chiamata tramite l'array arguments. Quello che fanno le prime righe di codice di ajaxGet predisporre un array con il primo elemento settato a una stringa arbitraria (che sar poi rimpiazzata dal testo della riposta HTTP), e tutti gli altri argomenti settati al valore passato dall'utente ad ajaxGet come argomenti addizionali. In pratica questo array sar utilizzato per chiamare l'handler quando la richiesta Ajax completa. Infatti sotto si procede alla creazione dell'handler vero della richiesta, quello che poi chiamer l'handler pi astratto, in pratica il vero handler fa da wrapper o da interfaccia per usare un termine italiano a quello di pi alto livello. Utilizzando la funzione ajaxOk il vero handler controlla che la richiesta abbia avuto buon fine (altrimenti non fa nulla), in caso positivo setta il primo elemento dell'array a alla risposta ottenuta. Ora l'array a contiene una la lista degli argomenti con cui richiamare l'handler di alto livello, e il gioco fatto. Si noti come sia l'array a che l'argomento handler della funzione ajaxGet siano memorizzati nella chiusura assegnata alla variabile myHandler. Ecco dunque a cosa servivano le chiusure in questa nostra libreria.

La funzione apply
Siamo all'ultima riga di codice che rimane oscura: return handler.apply(this, a); Cosa fa apply?. Il problema il seguente: l'handler reale deve chiamare il nostro handler di alto livello con la lista di argomenti settati nell'array a. Come si richiama una funzione utilizzando come argomenti gli elementi di un array? In breve se ho un array che contiene gli elementi "a", "b" e "c", e una funzione f(), vorrei avere qualcosa che produca l'effetto di una chiamta a f("a","b","c"). Il metodo apply di ogni oggetto funzione Javascript fa proprio questo. A questo punto dovrebbe essere tutto chiaro, le seguenti righe di codice non fanno altro che creare la richiesta e assegnarla alla variabile globale ajax_req, e finalmente spedire la richiesta.

La variabile globale
Come avete visto anche se nell'utlizzo della nuova interfaccia non c' traccia di variabili globali, nella implementazione l'abbiamo utilizzata. Ci era in questo caso desiderabile perch la funzione CreateXmlHttpReq si occupa sia di creare l'oggetto necessario alla richiesta XmlHttpReq che di settare l'handler. Separando tale funzione in due parti, una che crea la richiesta ed una che setta l'handler, la necessit di una variabile globale non sussiste pi, ma
http://antirez.com/articoli/spaghettiajax.html Pagina 14 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

poich viene fatta al massimo una richiesta Ajax per volta e non volevo rimettere le mani nel codice esposto nella prima parte per non creare confusione ho preferito questa soluzione. In realt non c' alcun motivo per non registare anche l'oggetto della richiesta nella chiusura, dunque una buona esercitazione quella di riscrivere il codice in modo da evitare le variabili globali (anche se nella vita reale l'implementazione esposta potrebbe essere pi conveniente perch la parte incompatibile tra i diversi browser viene isolata in una sola funzione).

Internet Explorer 5
Purtroppo il codice sopra esposto non funzioner con Internet Explorer 5, perch tale browser non implementa apply. Siccome ancora c' circa l'un percento della popolazione di internet che utilizza tale browser bene sopportarlo in qualche modo. A tal fine ho scritto una implementazione di apply utilizzando la funzione eval: function myDummyApply(funcname,args) { var e = "funcname("; for (var i = 0; i < args.length; i++) { e += "args["+i+"]"; if (i+1 != args.length) { e += ","; } } e += ");" return eval(e); } Anche ajaxGet va modificata per utilizzare tale funzione se la apply reale fallisse. Ecco dunque il codice integrale completo di ogni pezzo che implementa l'interfaccia Ajax comoda da usare. (30 Maggio 2007) Nota: la funzione e' stata aggiornata per memorizzare l'oggetto della richiesta Ajax nella chiusura, questo significa che la nuova funzione ora gestisce richieste simultanee senza problemi. Questa modifica e' stata fatta nel codice che uso in produzione da un anno ma ho sempre dimenticato di metterla online, scusate per l'inconveniente. Consiglio a tutti di utilizzare questa nuova versione. /* Copyright(C) 2005,2006,2007 Salvatore Sanfilippo <[email protected]> * All Rights Reserved. */ // Create the XML HTTP request object. We try to be // more cross-browser as possible. function CreateXmlHttpReq(handler) { var xmlhttp = null; try { xmlhttp = new XMLHttpRequest(); } catch(e) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } } xmlhttp.onreadystatechange = handler; return xmlhttp; } Nel codice finale ci sono due aggiunte. La prima una funzione // An handler that does nothing, used for AJAX requests that DummyHandler che non fa proprio niente. Si usa come handler Ajax // don't require a reply and are non-critical about error conditions. quando si vuole semplicemente fare una richiesta al server senza function DummyHandler() { avere return risposta. Si potrebbe modificare la ajaxGet in modo da alcuna true; accettare false come handler e capire da sola che non deve chiamarlo } in tal caso. // Shortcut for creating a GET request and get the reply La seconda aggiunta of una versione potenziata di ajaxGet che trivial // This few lines code can make Ajax stuff much more si chiama ajaxGetRand cheto avoid patterns in programs is sane! // to write, and... aggiunge automaticamente alla richiesta un parametro casuale per evitare i problemi di cache di Internet Explorer function ajaxGet(url,handler) { esposti nella = new parte dell'articolo. var a prima Array("placeholder"); for (var j=2; j<arguments.length; j++) { a[a.length] = Gestione degli errori arguments[j]; } var ajax_req = CreateXmlHttpReq(DummyHandler); Per completezza ci sarebbe ancora una cosa da fare per migliorare var myhandler = function() questo codice: si dovrebbe gestire {la condizione di errore delle var content = ajaxOk(ajax_req); if (content !== false) {
http://antirez.com/articoli/spaghettiajax.html Pagina 15 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

richieste e visualizzare un alert, qualcosa come Problemi di comunicazione col server se la richiesta fallisce. Poich questo articolo ormai sfiora le 60000 battute, non mi resta che lasciare anche questo come esercizio al lettore volenteroso, e passare alle conclusioni.

Escape degli argomenti della richiesta


Quando si fa una qualunque richiesta HTTP utilizzando il metodo GET, necessario fare l'escape degli argomenti nella richiesta in modo da essere certi che non contengano caratteri che in una query sono considerati speciali come ad esempio ?, +, & ed altri ancora. A questo scopo bisogna utilizzare la funzione Javascript encodeURIComponent che pi o meno l'equivalente della funzione PHP urlencode. Dunque se devo passare un parametro tramite ajaxGet ad uno script PHP scriver qualcosa come: ajaxGet("/script.php?parametro="+encodeURIComponent(parametro),myHandler); I browser pi vecchi quali il solito IE 5 non possiedono tale funzione, ma una meno sicura che non fa l'escape in maniera corretta di alcuni caratteri (come il +), chiamata escape (la funzione inversa unescape). Se dovete passare parametri che sicuramente non contengono uno spazio potete accontentarvi di escape, altrimenti necessario usare la giusta funzione. Se proprio volete il massimo della compatibilit vi consiglio di scrivere una funzione per conto vostro che faccia l'escape di tutti i caratteri tranne alcuni contenuti in una lista (i caratteri alfanumerici nell'intervallo A-z e 0-9 non hanno bisogno di alcun escape).

Conclusioni
Forse avrei potuto fare un articolo lungo un decimo, mostrando direttamente il poco codice che serve a rendere Ajax pi comodo ed astratto da utilizzare, e rimandando ogni parte meno ovvia del codice a riferimenti esterni, avrei anche evitato di spendere le quasi 8 ore che ci sono volute per scrivere questo articolo, ma non credo sarebbe stato lo stesso. Le risorse in inglese su Ajax abbondano mentre in italiano c' ben poco, dunque pensavo che sarebbe stato utile avere in un unico articolo una introduzione ad Ajax e un approfondimento sulle tecniche evolute di programmazione con Javascript. Spero vivamente che questo articolo serva ad almeno un programmatore di lingua italiana a scoprire qualcosa di nuovo. Ringrazio tutti i lettori che sono arrivati a leggere fino a questo punto, non erano argomenti semplicissimi. Alla prossima.

Javascript playground
La Javascript console di Firefox (IE manco la possiede) non esattamente il massimo per sperimentare con Javascript, problema che ho avvertito pi volte in passato e che sto constatando ancora una volta mentre scrivo questo articolo, per questo motivo propongo la Javascript playground, una area di testo e relativa finestra dove va a finire l'output, e che serve ovviamente per giocare con Javascript. L'utilizzo semplice: scrivete uno script nell'area di testo arancione, premete "esegui", e vedete l'output nella parte grigio chiara. Per emettere l'output dovete usare due funzioni normalmente non disponibili in Javascript ma implementate qui di proposito: echo, e clearscreen. La prima prende un argomento e lo stampa nella finestra di output, la seconda cancella tutto il contenuto dell'area di output. E' pi facile guardare l'esempio che spiegare come funziona mi sa :)

http://antirez.com/articoli/spaghettiajax.html

Pagina 16 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

clearscreen(); for (var i = 0; i < 10; i++) { echo(i+"\n"); }

0 1 2 3 4 5 6 7 8 9

Esegui

Cancella

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Italy License.

PROGRAMMING AND WEB


Welcome, this blog is about programming, web, open source projects I develop, and rants I love to share from time to time. From the point of view of a programmer that loves to define himself a craftsman.

HOT ARTICLES

NEWSLETTER

How to take advantage of Redis just adding it to your stack Everything about Redis 2.4 It's possible to Redis Documentation Fiesta 2 receive new posts Redis Manifesto in your mailbox Scripting branch released writing your email What's wrong with 2006 programming? address and On the web server scalability and speed are almost the same thing hitting the Redis Presharding subscribe button: Auto Complete with Redis Redis and scripting full listing
Subscribe

Delivered FeedBurner

by

Send me a feedback:

I wish to see an article about

send

Copyright (C) 2006-2011 Salvatore Sanfilippo - Valid xhtml strict - mobile edition

http://antirez.com/articoli/spaghettiajax.html

Pagina 17 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

http://antirez.com/articoli/spaghettiajax.html

Pagina 18 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

http://antirez.com/articoli/spaghettiajax.html

Pagina 19 di 20

Spaghetti Ajax: guida ajax in italiano

22/08/11 18:11

http://antirez.com/articoli/spaghettiajax.html

Pagina 20 di 20

Potrebbero piacerti anche