mercoledì, novembre 26, 2014

Ajax in azione

Con questo post, vi mostrerò come implementare richieste asincrone ad un componente server.

Per rendere l'esempio funzionante, ho creato una piccola applicazione web che risponde ad ogni richiesta che riceve, con la lista di due libri in formato json.

La richiesta partirà in modalità asincrona da questa stessa pagina che risiede su un dominio (blogger.com)  diverso da quello su cui è installata la mia applicazione (herokuapp.com)

Per motivi di sicurezza, non sarebbe possibile fare richieste asincrone in javascript ad un dominio diverso da quello da cui proviene il frammento javascript stesso. (same-origin policy)

Per effettuare una richiesta asincrona ad un server, utilizzando javascript standard, si utilizza un codice di questo tipo, dove ho omesso, per semplicità, eventuali controlli d'errore
  
 var xmlhttp = new XMLHttpRequest();  
 xmlhttp.onreadystatechange=function() {  
   document.getElementById("contenitore").innerHTML= xmlhttp.responseText;  
 };  
 xmlhttp.open("GET","risorsa/?eventualeparametro=valore",true);  
 xmlhttp.send();  

I passi per eseguire una richiesta asincrona sono i seguenti:
  1. istanziare un oggetto con la funzione costruttore XMLHttpRequest
  2. configurare su questo oggetto la funzione di callback che sarà eseguita quando arriverà la risposta dal server
  3. configurare il tipo di richiesta, in questo caso GET, e l'indirizzo della risorsa a cui effettuare la richiesta, che deve risiedere sullo stesso server, concatenendo all'indirizzo eventuali parametri
  4. mandare, in modalità asincrona, la richiesta: la send ritorna subito, non è bloccante. 
  5. appena il server risponde, cambierà lo stato dell'oggetto XMLHttpRequest e dunque verrà eseguita la funzione di callback che, in questo caso, riempirà il nodo che ha id = 'contenitore' con la risposta che è arrivata dal server
Se provassimo ad utilizzare questo frammento di codice utilizzando l'indirizzo reale dell'applicativo che ho sviluppato (https://ajaxjsonpexample.herokuapp.com/),  non otterremmo il risultato sperato, per il noto problema della same-origin policy.

Per ovviare a questa limitazione, nel tempo sono nate una serie di veri e propri hack, il piu' utilizzato dei quali va sotto il nome di jsonp, dove p sta per padding .

In sintesi, si deve fare in modo che la risorsa server ritorni i dati effettivi in formato json, come se fossero il parametro di una funzione:

 callback([{titolo: 'Il signore degli anelli'},{titolo: 'guerra e pace'}])  

La mia applicazione, ritorna al chiamante proprio questa stringa.

Se aggiungiamo alla nostra pagina, dinamicamente, un nodo script il cui attributo src punti all'indirizzo della mia applicazione web, il run time javascript interpreterebbe la risposta del server come una istruzione da eseguire

 callback([{titolo: 'Il signore degli anelli'},{titolo: 'guerra e pace'}])  

Ci basta allora aggiungere una proprietà dal nome callback sull'oggetto globale window, di tipo funzione, che gestisca l'array di libri ricevuti come parametro.

Provate a cliccare il bottone seguente




Ho messo l'implemetazione dell'esempio (codice lato client) su github. Fate riferimento a questo post per capire come fare ad ottenerli sulla vostra macchina.

Se aprite i web tools con F12 e andate sul tab networking e poi script, e cliccate di nuovo il bottone,potrete effettivamente osservare la richiesta fatta al server esterno con la relativa risposta.



In un prossimom post vi parlerò di heroku e di come sia facile pubblicare una nostra applicazione web su questa piattaforma di hosting che supporta già ruby,php,nodejs,java,python,scala,clojure.

L'applicazione web che ho installato su heroku è scritta in java, è costituita da una semplice servlet che scrive direttamente sulla risposta la stringa json che rappresenta l'array dei due libri.

Alla prox.
Ivan

Nessun commento:

Posta un commento