AJAX – Fondamenti di base

Si sente spesso parlare di AJAX. E sempre più spesso lo usiamo e ne appreziamo la rinnovata usabilità che riesce a dare alle web application.

Senza stare a fare troppi proclami, che sarebbero poi mere ripetizioni di cose lette e stralette, è innegabile dire che AJAX ha letteralmente rivoluzionato la concezione stessa di fare web.

Ho intenzione di fare un piccolo escursus. Un post "appunto personale" giusto per ricordarmi le basi del funzionamento di AJAX. Senza stare troppo a dire perchè è bello e quanto sia figo.

Asincronia.

E’ una delle caratteristiche fondamentali di quello che non è un linguaggio di programmazione puro. Ma l’unione di più processi di scripting che interagiscono fra di loro. E’ possibile inviare richieste di tipo POST e GET senza dover ricaricare la pagina.

In termini di risparmio di banda sul server e di velocizzazione degli script non ci sono eguali al momento.

JavaScript.

In AJAX si concretizza soprattutto nella capacità di aggiornare il contenuto di una pagina senza doverla nuovamente ricevere dal server. Questa caratteristica, associata all’asincronismo, fa vivere una pagina HTML.

XML.

In realtà non necessario, ma pur sempre prezioso. Nella sua stesura standard le risposte dal server vengono fornite al client in formato XML, facilmente manipolabile, sicuro da utilizzare, standardizzato quanto basta per essere sempre utile.

[MORE]

XMLHttpRequest per richieste in background.

La principale arma di attacco di AJAX si concretizza nell’oggetto XMLHttpRequest. Una volta attivato è possibile utilizzare tutti i suoi metodi. I principali sono:

  • open(url, asynch): prepara la richiesta HTTP e specifica se questa è asincronica o meno.
  • send(): invia la richiesta HTTP.
  • abort(): cancella una richiesta HTTP.

L’oggetto supporta altri metodi, ma per il momento soffermiamoci su questi. Adesso veniamo alle proprietà che può avere:

  • readyState: può assumere diversi valori. Più avanti si vedrà quanto può risultare utile la gestione degli eventi in funzione del valore di questa proprietà.
    • 0: non è stato eseguito open();
    • 1: è stato eseguito open(), ma non ancora send();
    • 2: è stato eseguito send();
    • 3: responseText contiene dati parziali.
    • 4: richiesta completata.
  • onreadystatechange: proprietà che vive in funzione di readyState e viene chiamata in occasione di ogni modifica di questa.
  • responseText: la risposta HTTP in formato testo.
  • responseXML: la risposta HTTP in formato XML.
  • status: importantissimo, perchè ritorna in un numero lo stato della richiesta HTTP (200 vuol dire che la richiesta è andata a buon fine, 404 vuol dire che l’url di richiesta non è stato trovato, 500 vuol dire internal server error, e via dicendo).
  • statusText: come status, ma in formato testo.

La mia prima richiesta in background.

Procediamo ora con lo scrivere un esempio di richiesta XMLHttpRequest. Per prima cosa dobbiamo sottolineare che l’oggetto XMLHttpRequest è evocabile come proprietà dell’oggetto di più alto livello window.

if(window.XMLHttpRequest){

  myReq = new XMLHttpRequest();

  myReq.onreadystatechange = myFunc;

  myReq.open(method,url,bool);

  myReq.send(null);

}

Cosa abbiamo fatto? E’ abbastanza semplice. Se l’oggetto XMLHttpRequest è evocabile lo istanziamo tramite new. Associamo la funzione myFunc() al cambiamento di status e prima di tutto apriamo la richiesta con un open, preparando i dati per l’invio:

  • method: GET o POST;
  • url: la pagina a cui inviare i dati (che verosimilmente saranno trattati via script);
  • bool: può essere true o false. Definisce se la richiesta è asincronica o meno (ricordi che l’oggetto XMLHttpRequest gestiste anche richieste sincroniche).

Per gli utenti che usano Internet Explorer.

Il modus operandi descritto sopra funzionerà con praticamente tutti i browser. Anche con IE7 che fortunatamente include in maniera nativa l’oggetto XMLHttpRequest.

Alla data di stesura di questo articolo, nonostante IE7 sia ormai rilasciato in versione final, l’uso di versioni precedenti del browser Micro$oft è ancora molto diffuso (le statistiche di questo blog mostrano un uso di IE6 pari al 38% dei contatti).

Nel caso di IE6 o precedenti versioni, l’oggetto XMLHttpRequest non esiste, e bisognerà evocare l’oggetto ActiveXObject con il metodo Microsoft.XMLHTTP o Msxml2.XMLHTTP.

Per la verità dovrebbe bastare Msxml2.XMLHTTP, in quanto la quasi totalità delle versioni di IE precedenti alla versione 7, seppur installate tempo addietro, dovrebbero essere state aggiornate via Windows Update, ma dato che non possiamo sapere la cosa con certezza, costruiamo la nostra richiesta di conseguenza.

Ecco come faremo per inviare e gestire richieste in background con IE6.

if(window.ActiveXObject){

  myReq = new ActiveXObect("Microsoft.XMLHTTP");

  if(!myReq){

    myReq = new ActiveXObject("Msxml2.XMLHTTP");

  }

  if(myReq){

    myReq.onreadystatechange = myFunc;

    myReq.open(method,url,bool);

    myReq.send(null);

  }

}

Creiamo una funzione all comprensive.

Adesso cerchiamo di mettere in pratica tutto quello che abbiamo visto con una funzione che ci permetta di gestire in modo dinamico la cosa.

function AJAXReq(method,url,bool){
  if(window.XMLHttpRequest){
    myReq = new XMLHttpRequest();
  } else
 
  if(window.ActiveXObject){
    myReq = new ActiveXObject("Microsoft.XMLHTTP");
   
    if(!myReq){
      myReq = new ActiveXObject("Msxml2.XMLHTTP");
    }
  }
 
  if(myReq){
    execfunc(method,url,bool);
  }else{
    alert("Impossibilitati ad usare AJAX");
  }
}

/*Se esiste myReq farò eseguire questa funzione
  che a sua volta chiamerà una terza funzione*/

function execfunc(method,url,bool){
  myReq.onreadystatechange = handleResponse;
  myReq.open(method,url,bool);
  myReq.send(null);
}

Volendo possiamo anche definire una fuzione handleResponse() giusto per visualizzare un output vero. La scrivo per com’è. In un altro articolo vedremo meglio come gestire la cosa.

function handleResponse(){
  if(myReq.readyState == 4){
    if(myReq.status == 200){
      alert(myReq.responseText);
    }else{
      alert("Niente da fare, AJAX non funziona :(");
    }
  }
}

Un piccolo esempio lo trovate in questa pagina. Presto scriverò qualcosa sulla gestione delle risposte.

10 thoughts on “AJAX – Fondamenti di base”

  1. AJAX è decisamente utile, per tutte le cose che consente di fare. Ma io ho trovato molto meglio affidarmi ad un framework esterno che verrà mantenuto aggiornato e spero anche retrocompatibile, per evitare di stare appresso alle modifiche che credo salteranno fuori in una tecnologia che è ancora giovane.

    Io, dicevo, uso dojo … e lo consiglio. Anche a te.

  2. non mi è chiara una cosa, se la chiamata è asincrona e il programma chiamato ci mette un po' di tempo a terminare, viene eseguita la handleResponse subito con readyState=0 e poi il programma prosegue.Come si fa a dire alla procedura che deve restare lì in attesa di ricevere il readyState=4?

  3. @ mob: la funzione handleResponse() parte ad ogni readystatechange.

    Ma se vedi nella funzione stessa, c'è una codizione di esecuzione delle istruzioni interne di handeResponse

    if(myReq.readyState == 4)

    Ogni volta che readyState cambia, passando da 0 a 1 a 2, fino a 4 che vuol dire richiesta terminata, si esegue la funzione handleResponse(), che però diventerà perfettamente operativa solo con readyState == 4.

    In realtà handleResponse() non sta in attesa, ma si esegue per 5 volte. Solo che si blocca subito le prime 4 perchè readyState è diverso da 4.

  4. A me da accesso negato… uff… devo capire che diavolo ha.
    Purtroppo temo di non poter usare jQuery, in quanto sto preparando un componentino da inserire nelle pagine in js.

Comments are closed.