Ajax

Introduzione
Il metodo XMLHttpRequest (XHR) consente ai browser di comunicare con il server senza ricaricare la pagina. Questo metodo, noto anche come Ajax (Asincrono JavaScript e XML, in inglese Asynchronous JavaScript and XML), consente alle applicazioni di creare interattività.

Le richieste Ajax vengono eseguite dal codice JavaScript, il quale invia una richiesta a un URL e quando riceve una risposta, una funzione di ritorno può essere eseguita il quale riceve come argomento la risposta del server e ne fa qualcosa con questa. Visto che la risposta è asincrona, il resto del codice dell’applicazione continua a funzionare, quindi è imperativo che una funzione di ritorno venga eseguita per gestire la risposta.

Attraverso vari metodi, jQuery fornisce il supporto per AJAX, che consente astrarre le differenze che possono esistere tra i browser. I metodi in questione sono $.get(), $.getScript(), $.getJSON(), $.post() e $().load().

Sebbene la definizione di Ajax ha la parola “XML”, la maggior parte delle applicazioni non utilizzare questo formato per il trasporto dei dati, ma al suo posto utilizza testo formato HTML o informazioni in JSON (JavaScript Object Notation).

In generale, l’Ajax non funziona in domini diversi. Tuttavia, ci sono delle eccezioni, come i servizi che forniscono informazioni in formato JSONP (JSON with Padding), che permettono funzionalità limitate in domini diversi.

Concetti chiave
L’uso corretto dei metodi di Ajax richiede in primo luogo la comprensione di alcuni concetti chiave.
GET vs. POST
I due metodi HTTP più comuni per l’invio di una richiesta a un server sono GET e POST. E ‘importante capire l’uso di ciascuno.

Il metodo GET dovrebbe essere utilizzato per operazioni non distruttive – cioè, operazioni in cui si sta “ottenendo” dati dal server, e non “modificando”. Per Esempio, una query per una ricerca potrebbe essere una richiesta GET. D’altra parte, le richieste GET possono essere memorizzate nella cache del browser e può generare comportamenti imprevedibili se non attesi. In generale, le informazioni inviate al server, vengono inviati in una stringa di dati (in inglese query string).

Il metodo POST dovrebbe essere utilizzato per operazioni distruttive – cioè operazioni in cui vengono incorporate informazioni nel server. Per Esempio, quando un utente salva un articolo in un blog, questa azione dovrebbe usare POST. D’altra parte, con questo tipo di metodo non viene memorizzato nella cache del browser. Inoltre, una stringa di query può essere parte della URL, ma le informazioni tendono ad essere inviate separatamente.

Tipi de Dati
In generale, jQuery ha bisogno alcune istruzioni sul tipo di informazioni da ricevere quando si effettua una richiesta Ajax. In alcuni casi, il tipo di dati è specificato dal nome del metodo, ma in altri casi dovrebbe essere specificato come perte della configurazione del metodo:
text
Per il trasporto di semplici stringhe.
html
Per il trasporto di blocchi di codice in HTML che verranno inseriti nella pagina.
script
Per aggiungere un nuovo script con codice JavaScript alla pagina.
json
Per trasportare le informazioni in formato JSON, il quale può includere stringhe, array e oggetti.

Dalla versione 1.4 della libreria, se l’informazione JSON non è correttamente formattata, la richiesta potrebbe non riuscire. Visita http://json.org per i dettagli sulla corretta formattazione dei dati JSON.

Si consiglia di utilizzare i meccanismi che possiede il linguaggio lato server per generare le informazioni in JSON.

jsonp
Per trasportare le informazioni JSON da un dominio all’altro.
xml
Per trasportare le informazioni in formato XML.
Nonostante i diversi tipi di dati che possono essere utilizzati, è raccomandato utilizzare il formato JSON, dal momento che è molto flessibile, consentendo per esempio, inviare al tempo stesso informazioni piatte e HTML.
Asincronismo
Perché, per impostazione predefinita, le chiamate Ajax sono asincrone, la risposta del server non è immediatamente disponibile. Per ssempio, il seguente codice non dovrebbe funzionare:
[code lang=”javascript”] var response;
$.get(‘foo.php’, function(r) { response = r; });
console.log(response); // undefined – indefinito!
[/code]
Invece, è necessario specificare una funzione di ritorno, questa funzione verrà eseguita quando la richiesta si sia conclusa correttamente in quanto è allora che la risposta del server è pronta.
[code lang=”javascript”] $.get(‘foo.php’, function(response) { console.log(response); });
[/code]
Politiche di Stessa Origine e JSONP
In generale, le richieste Ajax sono limitati a usare lo stesso protocollo (http o https), la stessa porta e lo stesso dominio di origine. Questa limitazione non si applica agli script caricati tramite i metodi di jQuery Ajax.

L’altra eccezione è quando si fa una richiesta di riceverà una risposta in formato JSONP. In questo caso, il fornitore della risposta dovrebbe rispondere alla richiesta con uno script che può essere caricato utilizzando il tag <script>, evitando così la limitazione ad effettuare richieste dallo stesso dominio. Questa risposta avrà le informazioni richieste, contenuta in una funzione.

Ajax e Firebug
Firebug (o l’ispettore WebKit che viene in Chrome o Safari) sono strumenti essenziali per lavorare con le richieste Ajax, giacché è possibile osservare dalla scheda console di Firebug (o andando in Risorse > Pannello XHR dalla finestra di ispezione Webkit) e vedere i dettagli di queste richieste. Se qualcosa non va a buon fine quando si lavora con l’Ajax, questo è il primo posto dive si dovrebbe andare per sapere quale è il problema.
Metodi Ajax de jQuery
Come indicato sopra, jQuery ha diversi metodi per lavorare con Ajax. Tuttavia, tutti si basano sul metodo $.ajax, quindi, la sua comprensione è obbligatoria. Di seguito si spiegherà il metodo e poi s’indicherà un breve riassunto sugli altri metodi.

È generalmente preferibile utilizzare il metodo $.ajax piuttosto che altri, visto che offre più funzionalità e la sua configurazione è molto comprensibile.
$.ajax

Il metodo $.ajax è configurato attraverso un oggetto che contiene tutte le istruzioni che necessita jQuery per completare la richiesta. Questo metodo è particolarmente utile perché offre la possibilità di specificare azioni se la richiesta sia riuscita o meno. Inoltre, essendo impostato attraverso un oggetto, è possibile impostare le proprietà separatamente, rendendo più facile il riutilizzo del codice. È possibile visitare http://api.jquery.com/jQuery.ajax/ per consultare la documentazione sulle opzioni disponibili nel metodo.
7.1: Utilizzare il metodo $.ajax
[code lang=”javascript”] $.ajax({
// l’URL per la richiesta
url : ‘post.php’,

// invio di informazioni
// (è anche possibile utilizzare una stringa di dati)
data : { id : 123 },

// specificare se si tratta di una richiesta POST o GET
type : ‘GET’,

// il tipo di informazioni
// che ci si attende come risposta
dataType : ‘json’,

// codice da eseguire se la richiesta viene accettata;
// la risposta è passata come argomento alla funzione
success : function(json) {
$(‘<h1/>’).text(json.title).appendTo(‘body’);
$(‘<div class="content"/>’)
.html(json.html).appendTo(‘body’);
},

// codice da eseguire se la richiesta fallisce;
// sono passati come argomenti alla funzione
// l’oggetto della petizione in codice grezzo
// e lo stato della richiesta
error : function(xhr, status) {
alert(‘Spiacente, c\’è stato un problema!’);
},

// codice da eseguire indipendentemente dal
// fatto se la richiesta riesca.
complete : function(xhr, status) {
alert(‘Richiesta fatta!’);
}
});
[/code]

Un chiarimento sul parametro dataType: se il server restituisce informazioni differenti dal formato specificato, il codice fallirà e la ragione perché lo faccia non è sempre chiara, perché la risposta HTTP non mostrerà alcun errore. Quando si lavora con le richieste Ajax, assicurarsi che il server invii il tipo di informazioni che si richiede e verificare che il Content-type sia esattamente al tipo di dati richiesti. Per esempio, per le informazioni in formato JSON, il Content-type dovrebbe essere application/json.
Opzioni del metodo $.ajax
Il metodo $.Ajax ha molte opzioni di configurazione, ed è proprio questa caratteristica che lo rende un metodo molto utile. Per un elenco completo delle opzioni disponibili, consultare http://api.jquery.com/jQuery.ajax/; le seguenti sono le più comuni:
async
Imposta se la richiesta è asincrona o meno. Di default il valore è true. È necessario essere consapevoli che se l’opzione è impostata su false, la richiesta bloccherà l’esecuzione di altri codici fino a quando la richiesta sia completata.
cache
Impostare se la richiesta viene memorizzata nella cache del browser web. Di default è true per tutti i dataType fatta eccezione per “script” e “jsonp”. Quando il valore è false, si aggiunge una stringa anti-cache alla fine della URL della richiesta.
complete
Imposta una funzione di retrochiamata che viene eseguita quando la richiesta sia stata completata, anche se ha fallito. La funzione riceve come argomenti l’oggetto della richiesta in grazzo e il codice di status della stessa richiesta.
context
Imposta l’ambito in cui vengono eseguite le funzioni di retrochiamata. (per Esempio definisce il significato di this all’interno delle funzioni). Di default this fa riferimento all’oggetto passato in origine al metodo $.ajax.
data
Consente di impostare le informazioni da inviare al server. Questo può essere un oggetto come una stringa di dati (per esempio foo=bar&baz=bim).
dataType
Consente di impostare il tipo di informazioni da ricevere in risposta dal server. Se nessun valore è specificato, per impostazione predefinita, jQuery controlla il tipo MIME che ha la risposta.
error
Imposta una funzione di retrociamata da eseguire se si tratta di un errore nella petizione. Detta funzione prende come argomenti l’oggetto della richiesta grezza e il codice di status della richiesta stessa.
jsonp
Imposta il nome della funzione di retrochiamata da inviare quando viene effettuata una richiesta JSONP. Di default il nome è “callback”.
success
Imposta una funzione da eseguire se la richiesta ha avuto successo. Questa funzione prende come argomenti le informazioni della richiesta (convertito in un oggetto JavaScript nel caso sia dataType o JSON), lo status della stessa e l’oggetto della petizione in grezzo.
timeout
Imposta il tempo in millisecondi da considerare per una richiesta non riuscita.
traditional
Se il suo valore è true, viene utilizzato lo stile di serializzazione di dati utilizzati nelle versioni di jQuery prima della 1.4. Per maggiori dettagli visitate http://api.jquery.com/jQuery.param/.
type
Il tipo di richiesta, “POST” o “GET”. Di default il suo valore è “GET”. Altre tipi di richieste possono anche essere utilizzati come (come PUT e DELETE), ma possono non essere supportati da tutti i browser.
url
Imposta l’URL in cui è presentata la richiesta.
L’opzione url è obbligatoria per il metodo $.ajax.
Metodi convenienti
Se non si desidera utilizzare il metodo $.ajax, e non necessita manipolare o gestire gli errori, esistono altri metodi più adatti per le richieste Ajax (sebbene, come notato in precedenza, questi sono basati al metodo $.ajax con valori prestabiliti di configurazione).
I metodi che fornisce la libreria sono:
$.get
Fa una richiesta GET a un URL previsto.
$.post
Fa una richiesta POST a un URL previsto.
$.getScript
Aggiunge uno script alla pagina.
$.getJSON
Fa una richiesta GET a un URL previsto e si aspetta che un dato JSON venga restituito.
url
L’URL in cui si farà la richiesta. Il suo valore è obbligatorio.
data
Le informazioni inviate al server. Il suo valore è facoltativo e può essere sia un oggetto o una stringa di dati (per esempio foo=bar&baz=bim).

Le informazioni inviate al server. Il suo valore è facoltativo e può essere sia un oggetto o una stringa di dati (per esempio foo=bar&baz=bim).
success callback
Una funzione opzionale che viene eseguita in caso la richiesta ha avuto successo. Questa funzione prende come argomenti le informazioni della richiesta e l’oggetto grezzo della petizione.
data type
Il tipo di dati che dovrebbero essere ricevuti dal server. Il suo valore è facoltativo.

Questa opzione è applicabile solo per i metodi dove non sia specificato il tipo di dati nel nome dello stesso metodo.
7.2: Utilizzare metodi appropriati nelle richieste Ajax
[code lang=”javascript”] // ottiene il testo piano o html
$.get(‘/users.php’, { userId : 1234 }, function(resp) {
console.log(resp);
});

// aggiunge uno script alla pagina e quindi
// esegue la funzione specificata
$.getScript(‘/static/js/myScript.js’, function() {
functionFromMyScript();
});

// ottiene i dati in formato JSON dal server
$.getJSON(‘/details.php’, function(resp) {
$.each(resp, function(k, v) {
console.log(k + ‘ : ‘ + v);
});
});
[/code]

$.fn.load
Il metodo $.fn.load è l’unico che può essere chiamato da una selezione. Questo metodo ottiene il codice HTML da un URL e riempire gli elementi selezionati con le informazioni ottenute. In concomitanza con l’URL, è possibile specificare facoltativamente un selettore, il quale otterrà il codice specificato in questa selezione.
7.3: Utilizzare il metodo $.fn.load per riempire un elemento
[code lang=”javascript”] $(‘#newContent’).load(‘/foo.html’);
[/code]
7.4: Utilizzare il metodo $.fn.load per riempire un elemento basato su una selezione.
[code lang=”javascript”] $(‘#newContent’).load(‘/foo.html #myDiv h1:first’, function(html) {
alert(‘Contenuto aggiornato!’);
});
[/code]
Ajax e Forms
Le funzionalità di jQuery con Ajax possono essere particolarmente utili per lavorare con i forms. Per esempio, il plugin jQuery Form Plugin è una estensione per aggiungere le funzionalità di Ajax sui forms. Ci sono due metodi che bisogna tenere conto quando si lavora con $.ajax sui forms: $.fn.serialize e $.fn.serializeArray.
7.5: Trasformare le informazioni da una form in una stringa di dati
[code lang=”javascript”] $(‘#myForm’).serialize();
[/code]
7.6: Creare un array di oggetti che contengono informazioni da un form
[code lang=”javascript”] $(‘#myForm’).serializeArray();

// crea una struttura come questa:
[
{ name : ‘field1’, value : 123 },
{ name : ‘field2’, value : ‘hello world’ }
] [/code]

Lavorare con JSONP
In tempi recenti, l’introduzione di JSONP, ha permesso la creazione di applicazioni ibride di contenuti. Molti siti offrono importanti offrono JSONP come servizio di informazione, cui si accede attraverso un’API (Application programming interface in inglese) predefinita. Un particolare servizio che fornisce informazioni in formato JSONP è Yahoo! Query Language, che lo utilizza per ottenere, per esempio, notizie sui gatti:
7.7: Usare YQL e JSONP
[code lang=”javascript”] $.ajax({
url : ‘http://query.yahooapis.com/v1/public/yql’,

// viene aggiunto come parametro il nome della funzione
// di ritorno, come specificato nel servizio di YQL
jsonp : ‘callback’,

// si indica jQuery che è atteso informazioni
// in formato JSONP
dataType : ‘jsonp’,

// si indica al servizio di YQL quale è l’informazione
// che si desidera e che la si vuole in formato JSON
data : {
q : ‘select title,abstract,url from search.news where query="cat"’,
format : ‘json’
},

// si esegue una funzione se
// la richiesta è andata a buon fine
success : function(response) {
console.log(response);
}
});
[/code]

jQuery si occupa di risolvere tutti gli aspetti complessi della richiesta JSONP. Tutto quello che si deve fare è specificare il nome della funzione di ritorno (in questo caso “callback”, come da specifica YQL) e il risultato finale sarà come una normale richiesta Ajax.
Eventi Ajax
Spesso si desidera eseguire una funzione quando una petizione si avvia o finisca, come per esempio, mostrare o nascondere un indicatore. Invece di definire queste funzioni all’interno di ogni richiesta, jQuery offre la possibilità di vincolare gli eventi Ajax agli elementi selezionati. Per un elenco completo degli eventi Ajax, è disponibile la pagina http://docs.jquery.com/Ajax_Events.
7.8: Mostra/Nascondi un indicatore utilizzando Eventi di Ajax
[code lang=”javascript”] $(‘#loading_indicator’)
.ajaxStart(function() { $(this).show(); })
.ajaxStop(function() { $(this).hide(); });
[/code]
Esercizi
Caricare contenuto esterno
Open the file /exercises/index.html in your browser. Use the file /exercises/js/load.js. Your task is to load the content of a blog item when a user clicks on the title of the item.

  • Creare un elemento div dopo il titolo di ogni titolo di articolo del blog e salvare un riferimento ad essi nell’elemento titolo utilizzando $.fn.data.
  • Vinculare un evento click al titolo, il quale utilizzerà il metodo $.fn.load per caricare in ogni div creato il contenuto appropriato dal file /exercises/data/blog.html. Non dimenticare di disattivare il comportamento predefinito dell’evento click.

Da notare che ogni titolo di articolo del blog in index.html include un link a questo articolo. Sfruttare l’attributo href di ogni link per ottenere il contenuto particolare di blog.html. Dopo aver ottenuto il valore dell’attributo, utilizzare il seguente form per elaborare le informazioni e convertirla in un selettore per l’uso in combinazione con $.fn.load:

[code lang=”javascript”] var href = ‘blog.html#post1’;
var tempArray = href.split(‘#’);
var id = ‘#’ + tempArray[1];
[/code]
Ricordatevi di usare console.log per assicurarsi che si sta facendo la cosa giusta.
Carricare contenuto utilizzando JSON
Aprire il file /exercises/index.html nel browser web. Eseguire ejericio utilizzando il file /exercises/js/specials.js. Il compito è quello di mostrare i dati dell’utente in un particolare giorno quando viene selezionato dal menù a discesa.

  • Aggiungere un elemento div dopo il form all’interno dell’elemento #specials; sarà lì il luogo dove si metteranno le informazioni da ottenere.
  • Vincolare l’evento change sull’elemento select; quando si apporta una modifica nella selezione, inviare una richiesta Ajax a /exercises/data/specials.json.
  • Quando la richiesta restituisce una risposta, utilizzare il valore selezionato nella select (suggerimento: $.fn.val) per trovare le informazioni appropriate nella risposta JSON.
  • Aggiungere un po’ di HTML con le informazioni ottenute nel div creato in precedenza.
  • Infine rimuovere il pulsante di invio (submit) del form.

Notare che ogni volta che cambia la selezione, si esegue una richiesta Ajax. Come si potrebbe modificare il codice per eseguire solo una richiesta e salvare le informazioni per trarre vantaggio quando si torna a modificare la selezione?