JSON… e quella virgola di troppo

Da tanto tempo si è affermato ormai JSON come formato per la trasmissione di dati perchè ritenuto più performante di XML.

Ormai quasi tutti i servizi Web 2.0 rispondono a delle richieste con dei buffer in formato JSON. Grazie al massivo uso di AJAX dell’oggetto XMLHttpRequest incentivato dall’adozione dei diversi framework di sviluppo JavaScript, JSON è diventato un formato di interscambio anche da e verso linguaggi che non ne hanno avuto necessità fino ad oggi (Si veda sul sito http://json.org le librerie prodotte per i vari linguaggi di programmazione).

Utilizzando JSON spesso si incorre in un comportamento diverso tra i vari browser.

Non si comportano diversamente nel trattare un oggetto, un array o una stringa, ma si comportano diversamente in uno specifico caso… Quale?

Prendiamo il JSON che segue:

var myJSONObject = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3',
};
alert(myJSONObject.key1);

Provando ad includere il codice sopra citato in una pagina HTML in alcuni browser il risultato è un messaggio di alert con il che riporta il testo “value1”. Internet Explorer Altri browser invece danno un errore sulla riga precedente all’alert.

Il problema come descrive già il titolo di questo articolo è nella virgola successiva al valore della key3.

Secondo la mia interpretazione (ma potrei sbagliarmi, so di non sapere  :-) ) è giusto che non dia errore in quanto la virgola è inteso come separatore di valori e potrei avere (o volere) un ultimo elemento vuoto nell’oggetto.

Io non ho trovato risposta a questo dilemma, neanche le RFC fanno riferimento a questo caso “anomalo”. Chi è che si comporta bene secondo voi?

Tutti per uno… XMLHttpRequest per tutti!

Introduzione

Ho deciso di scrivere questo tutorial perché negli ultimi tempi ho trovato molta confusione nell’utilizzo di sigle e definizioni. Relative all’oggetto XMLHttpRequest o addirittura all’idea di cosa sia AJAX.

Durante la lettura di questo articolo potrebbe essere propedeutica la consultazione contestuale degli script allegati.

Ci sono persone che interpretano AJAX semplicisticamente come il rendere dinamico (pieni di effetti) un sito di base statico, altre persone invece attribuiscono il termine ajax indiscriminatamente per qualsiasi tipo di operazione client/server. In effetti credo che il nome più opportuno per richieste client/server basate su script è XMLHttpRequest. Esso poi viene utilizzato per adempiere alle mansioni previste dai vari acronimi.

Significato degli acronimi

Il primo acronimo che credo aver sentito è stato proprio AJAX (forse perché è quello che si è diffuso con maggior velocità rispetto agli altri. Questo acronimo sta per Asynchronous Javascript And Xml ovvero nato con lo scopo di trattare richieste tramite javascript da e verso un server con notazione XML in modalità asincrona . Per eseguire questa funzione bisogna avvalersi dell’oggetto XMLHttpRequest.

Il secondo acronimo di cui mi ricordo essermi imbattuto è stato AJAJ che sta per Asyncrhonous Javascript and JSON. Uhm… un altro acronimo è saltato fuori. Il metodo migliore per descriverlo è riferendosi alla fonte ufficiale: http://www.json.org. Questo sistema appunto prevede che non ci sia un XML come risposta server ma una struttura nella notazione JSON (JavaScript Object Notation). Anche in questo caso per funzionare c’è bisogno dell’oggetto XMLHttpRequest.

Altro Acronimo in cui mi sono imbattuto: AHAH. Inizialmente l’avevo considerato una battuta… ma documentandomi ho riscontrato che effettivamente è un acronimo e sta per: Asynchronous Html And Http. Anch’esso si basa sull’XMLHttpRequest. Per evitare di dire cose errate o parziali suggerisco di consultare la fonte originale AHAH, Asynchronous Html And Http.

Facendo una ricerca su internet ho notato che l’acronimo AJAS è stato utilizzato su un articolo di Steve Karam “Putting the Express Back Into Oracle Application Express with AJAX“.

Ammaliato da tutti questi acronimi, ho deciso di inventarne uno anche io: AJAT ho fatto una ricerca su internet e non sono riuscito ad attribuirne la paternità per cui me la auto-attribuisco ma se tale acronimo fosse già stati menzionato da altri sarò ben lieto di segnalare i loro nomi come ideatori del termine.

AJAT significa: Asyncronous Javascript And Text mentre AJAS significa: Asynchronous Javascript And javaScript. Il primo prevede che il risultato dell’elaborazione server sia un Testo semplice non formattato secondo i tags dell’XHTML, l’altro invece prevede che in outuput sia ritornato uno Script Javascript da eseguire. Entrambi comunque fanno uso dell’oggetto XMLHttpRequest.

Una sintesi chiarificatoria

Sintetizzando, i cinque acronimi precedentemente utilizzati fanno tutti uso di una stessa metodologia di approccio al problema: è richiesto l’utilizzo di un oggetto XMLHttpRequest e la necessità di essere delle richieste Asicrnone.

Ma perché vengono introdotte queste nuove metodologie? Non basta fare il refresh di una pagina? La risposta è “Ni” ovvero l’idea sarebbe quella di caricare solo parte di una pagina attualmente visualizzata, se il browser del client lo consente, in alternativa provvedere a fare il caricamento di tutta la pagina. Almeno la filosofia che ne ho tratto è quella appena indicata.

Contesti d’uso

Con i presupposti che ad ora abbiamo definito, ciascuna metodologia è adeguata per un determinato problema.

Se per ipotesi volessimo gestire quindi una risposta di tipo XML la metodologia utilizzata prenderebbe il nome di AJAX. In alternativa assumerebbe uno degli acronimi precedentemente specificati. AJAJ per risposte in JSON, AHAH rimando alla fonte originale, AJAS per ottenere script javascript, AJAT per trattare risposte di tipo testo non formattato.

La tecnologia AJAX

Note preliminari

Questo articolo è stato scritto da Matteo Tinazzi. La pubblicazione su questo sito è stata autorizzata dall’autore.

Introduzione

AJAX è un acronimo che sta per Asynchronous Javascript And XML il che significa uno scambio di dati asincrono tra il server e il client attraverso javascript e XML.

Tanto per non farci impressionare dalla terminologia spieghiamo in parole semplici questo concetto: attraverso l’oggetto javascript xmlHttpRequest il nostro browser aprirà una nuova connessione verso il server e scaricherà il contenuto di una pagina “al volo”, cioè senza ricaricare la pagina principale. Questo ci permette di poter aggiornare i contenuti della nostra pagina iniziale senza doverla per forza ricaricare, il che ci farà (sia ai webmaster che ai visitatori) risparmiare tempo e banda.

Perchè viene chiamato in causa l’XML? Bhe semplice questo oggetto è stato creato appositamente per restituire un documento nel formato XML, il che permette una grande semplicità e flessibilità nel gestire i dati.

Per capire meglio il funzionamento vediamo innanzitutto come istanziare questo oggetto per i browser basati su ActiveX:

var xml = new ActiveXObject("Microsoft.XMLHTTP");

e per tutti gli altri:

var xml = new xmlHttpRequest();

Questa differenza è dovuta alle solite incompatibiltà tra browsers, ma fortunatamente, una volta istanziato, i metodi di questo oggetto sono uguali e sono sei:

  • abort() blocca la richiesta corrente.
  • getAllResponseHeaders() restituisce tutti gli header in formato stringa.
  • getResponseHeader(“etichetta”) restituisce un particolare header.
  • open(“metodo”,”URL”[,”Flag Sincronia”[,”nome utente”[,”passwrod”]]]) assegna all’oggetto l’URL da aprire, il metodo di invio dei dati (GET o POST), il FLag di sincronia che poi andremo a spiegare, uno username ed una password. Gli attributi racchiusi tra parentesi quadre sono opzionali.
  • send(“contenuto”) invia la richiesta impostata con open e il parametro opzionale “contenuto” passerà i dati POST in formato stringa.
  • setRequestHeader(“etichetta”, “valore”) imposta un header definito da “etichetta” ad un valore.

oltre a questi metodi l’oggetto ha anche sei proprietà:

  • onreadystatechange è il gestore di eventi che viene richiamato ad ogni cambio di stato della chiamata http
  • readyState indica i 5 stati del caricamento e va da 0 (non inizializzato) a 4 (caricamento completato)
  • responseText questa proprietà, dopo il completo caricamento, contiene una versione testuale della risposta del server
  • responseXML un oggetto di tipo DOM XML contenente i dati ritornati dal server
  • status il codice numerico ritornato dal server (200 OK, 404 Non trovato, 403 Non autorizzato ecc)
  • statusText la descrizione testuale del codice numerico ritornato da status

Funzionamento

Ora che abbiamo fatto una carrellata generale sull’argomento perchè non provarne subito il funzionamento?

Innanzitutto inizializziamo subito l’oggetto in questione

con il sistema di try e catch evitiamo di generare errori che bloccano lo script e creiamo l’istanza in base al tipo di oggetto supportato dal browser.

Effettuare una chiamata

Ora andiamo a scrivere una funzione che ci permetta di effettuare le chiamate ad un’altra pagina e che ci permetta di decidere se inviare i dati a queste usando il meodo $_GET o il metodo $_POST.

function initXml(){
    try {
        x = eval("new ActiveXObject('Microsoft.XMLHTTP');");
        return x;
    } catch(e){
        try{
            x = eval("new XMLHttpRequest();");
            return x;
        } catch(e){
            alert("Questo browser non supporta AJAX");
            x = false;
            return x;
        }
    }
}

Se analizziamo questa funzione noteremo che il funzionamento non è poi così complicato, infatti alla prima riga andiamo a richiamare la funzione che fa l’inizializzazione e ne salviamo il valore ritornato nella variabile xml e alla riga successiva andiamo a verificare che l’inizializzazione sia andata a buon fine, e quindi che la variabile xml sia diversa da false.

Il passo successivo è quello di assegnare una funzione al gestore dell’evento di cambio stato, in modo che ad ogni cambiamento della proprietà readyState questa venga richiamata. Il codice che ci permette di fare questo è xml.onreadystatechange = parseResponse; che assegna la funzione parseResponse.

Perchè abbiamo dovuto assegnare una funzione al gestore del cambio stato dell’oggetto? La risposta è semplice ma non ovvia e viene chiarita meglio nelle righe di codice succesive.

Sia per il metodo POST che per quello GET la prima operazione da eseguire è di impostare attraverso il metodo open i tre parametri principali per poter inviare una richiesta ad un’altra pagina e sono il metodo di invio dati (POST/GET), il nome del file della pagina da chiamare e il flag di sincronia.

Proprio quest’ultimo indica se il tipo di chiamata sarà sincrono (valore false) o asincrono (valore true), analizziamo le differenza tra i due tipi di chiamata.

La chiamata sincrona ed asincrona

La chiamata sincrona in poche parole “blocca” l’esecuzione dello script fino a che la pagina chiamata non è stata completamente caricata il che ci semplificherebbe la vita in quanto non sarebbè più necessario assegnare una funzione al gestore onreadystatechange in quanto dopo aver chiamato il metodo send subito dopo potremmo inserire il codice che interpreta la risposta, ma se la chiamata per qualche motivo tarda nel caricare i dati o ahimè si interrompe il collegamento al server ci ritorveremmo con il browser completamente bloccato, cosa che è meglio evitare.

La chiamata asincrona invece (ed è questa che andremo ad usare), invia la richiesta alla pagina e poi prosegue con il resto dello script senza più attendere nessuna risposta, infatti a gestire le risposte abbiamo delegato la funzione parseResponse.

Con questo metodo abbiamo risolto qualsiasi problema di connessione tra client e server e anche se i tempi di caricamento dei dati sono lunghi il client comunque non resta bloccato.

L’if che controlla il valore della variabile metodo ci semplifica la vita per differenziare i due metodi di invio dati alla pagina da richiamare, le diferenze tra il metodo GET e il POST sono semplici.

Per il GET file dovrà essere nella forma “nomefile.php?var=1&var2=2&var3=valore3” e quindi sarà “nomefile + variabili” come se fosse una stringa creata dal submit di una form con method GET e alla pagina chiamata dovremo inviare un null come contenuto del metodo send() in quanto tutti i dati sono già nella chiamata.

Per il POST, invece, ci sono due passaggi aggiuntivi e sono: spezzare file dove troviamo il carattere “?” recuperare parte successiva e nominarla args, mentre la parte precedente riassegnarla a file, facendo questo ci troveremo con file che sarà uguale a “nomefile.php” metre args varrà “var=1&var2=2&var3=valore3”. Il secondo passaggio sarà impostare un header che indicherà alla pagina che il Content-Type (tipo di contenuto) è ‘application/x-www-form-urlencoded’, praticamente indica che i dati saranno di tipo codificato come da una form con method POST.

Il metodo send nel caso di chiamate di tipo POST, oltre a chiamare la pagina impostata con il metodo open, sarà incaricato di inviare args che, come ricordiamo, contiene i dati.

Ora non ci resta che creare la funzione che si occupa di ricevere i risultati della nostra chiamata

function parseResponse(){
   if(xml.readyState==4 && xml.status=="200"){
      alert(xml.responseText)
   }
}

Per non dilungarci troppo, ed essendo questo un articolo sulle basi della tecnologia AJAX andremo semplicemente a verificare lo stato di caricamento dell’xml usando la sua proprietà xml.readyState e lo stato http attraverso xml.status, se il primo vale 4 (caricamento completato) e il secondo vale “200” (OK) visualizzeremo un alert con il contenuto testuale della chiamata usando xml.responseText.

%d blogger hanno fatto clic su Mi Piace per questo: