Neltuosito.itServizi Web Softvision  
 Accesso al Pannello di Controllo :  UserID  Password    Home    Registrazione
 
Servizi per il calcio
  Classifiche Campionati
  Risultati Campionati
Concorsi Pronostici
  Estrazioni Euro Jackpot
  Estrazioni del Lotto
  Risultati SuperEnalotto
  Risultati Totocalcio
  Risultati Totogol
  Risultati Big Match
  Risultati Tris
  Risultati V7
Cucina
Archivio Ricette
  Una Ricetta al Giorno
Vari
Codice Fiscale
  Archivio Barzellette
  Una Barzelletta al Giorno
Calcolo dell'IBAN
Calcolo del Peso Forma
Ricerca CAP
  Calcolo dei Bioritmi
   
Registrazione
Servizi FREE
Assistenza
Suggerimenti
Risorse Web Master
Guida Ajax
  Posizionamento Motori
  Posizionamento e Marketing
  Strategie per i Forum
    

Privacy Policy

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;
    }
}

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 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.

 

Nel codice finale ci sono due aggiunte. La prima è una funzione DummyHandler che non fa proprio niente. Si usa come handler Ajax quando si vuole semplicemente fare una richiesta al server senza avere alcuna risposta. Si potrebbe modificare la ajaxGet in modo da accettare false come handler e capire da sola che non deve chiamarlo in tal caso.

La seconda aggiunta è una versione potenziata di ajaxGet che si chiama ajaxGetRand che aggiunge automaticamente alla richiesta un parametro casuale per evitare i problemi di cache di Internet Explorer esposti nella prima parte dell'articolo.

Gestione degli errori

Per completezza ci sarebbe ancora una cosa da fare per migliorare questo codice: si dovrebbe gestire la condizione di errore delle 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).
 

 

 

 

Softvision - Via Cesare Battisti, 101 - 67051 Avezzano (AQ) - P.IVA 02081660660

Privacy Policy - Cookie Policy