Fuori programma
14-03-2010 15.51.00 GMT+02La battaglia di aNobii (parte 4)L'epilogo (con annunciato lieto fine) della storia dell'aNobii Filtered Blog Badge

Eccoci al finale della telenovela che ha portato alla nascita dell'aNobii Filtered Blog Badge.

Ci eravamo lasciati che armeggiavo con CORS (vedere la puntata precedente) per superare il problema della same-origin policy .
La soluzione anche se semplice era insoddisfacente perchè solo i browser di ultima generazione lo implementano (e nemmeno tutti).
Un'alternativa non troppo arzigogolata esisteva di sicuro. Ho perciò fatto un po' di ricerche tra i vari framework JavaScript in circolazione ed ho trovato che il famosissimo Dojo toolkit espone la funzione dojo.io.script.get.

E' importante tenere presente che questa funzione ha i seguenti requisiti (nel mio caso non creavano alcuna limitazione):

  • possono essere effettuate solo chiamate GET;
  • funziona solo in modalità asincrona, perciò deve essere implementata una funzione di callback;
  • la risposta deve essere in formato JSONP.

Avendo citato JSONP spiego brevemente cos'è, ma rimando per approfondimenti ed esempi a questo ottimo articolo. JSONP è un'evoluzione di JSON e sta per JavaScript Object Notation with Padding, dove oltre alla codifica secondo il protocollo JSON, la risposta viene restituita incapsulata come parametro di una chiamata ad una funzione concordata. La funzione concordata è quella di callback e quando la riposta della chiamata arriva, viene copiata nel corpo di un tag SCRIPT generato dinamicamente; questo ne causerà l'immediata esecuzione, ossia la chiamata al callback con il relativo valore della risposta. Sembra complicato, ma è l'uovo di colombo. Dojo implementa tutto questo lato client a noi non resta che creare la callback ed effettuare la chiamata a dojo.io.script.get.

Partendo dal codice da incollare nella pagina ospite, abbiamo che il codice della weblet si è veramente ridotto al minimo come volevo:

<!-- Cosimo Carbonelli's aNobii Filtered Blog Badge : begin -->
<div id="anobiiMiniShelf"></div>
<script type="text/javascript" 
  src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" 
  djConfig="parseOnLoad: true">
</script>
<script language="Javascript" type='text/javascript' 
  src='http://www.otherbit.com/modules/anobii/javaScript/ajax.js'>
</script>
<script language="Javascript" type='text/javascript' >                    
    function load() 
    {
        ajaxGET('cosimo', '4', '1');
    }
    dojo.addOnLoad(load);
</script>
<!-- Cosimo Carbonelli's aNobii Filtered Blog Badge : end -->

Dove abbiamo un DIV che consente di gestire a piacere il posizionamento della weblet, due link a codice JavaScript, uno alla libreria di Dojo e l'altro al mio codice ospitato sul server che eroga il servizio (con il vantaggio che l'utilizzatore finale non deve caricare nulla sul suo server, ammesso che possa). In ultimo, la chiamata alla mia funzione AJAX che consente di definire i parametri della weblet (utente, tag, pagina iniziale) che scatta, tramite Dojo, al completamento del caricamento dell'HTML.

// REQUIRES dojo

// set stylesheet on host document
function loadStylesheet(styleFile) 
{
    var link = document.createElement('link');
    link.rel = 'stylesheet';
    link.type = 'text/css';
    link.href = styleFile;
    document.getElementsByTagName('head')[0].appendChild(link);
}

// response handler for dojo.io.script.get
function handleResponse(data) 
{
    var targetNode = dojo.byId('anobiiMiniShelf');
    targetNode.innerHTML = data;
}

// calls the url using dojo.io.script.get
function ajaxGET(pId, tagId, pageNum) 
{   
    var targetNode = dojo.byId('anobiiMiniShelf');
    targetNode.innerHTML = '<span class="anobiiLoading">loading...</span>';
    
    // passes the parameters, the url, and the callback
    var jsonpArgs = {
                url: 'http://www.otherbit.com/modules/anobii/filterbytag.aspx',
                content: {
                     personId: pId,
                     tag: tagId,
                     page: pageNum,
                     callback: 'handleResponse'
                }
     };
    dojo.io.script.get(jsonpArgs);
}

// dojo requirement
dojo.require("dojo.io.script");

// set stylesheet
loadStylesheet('http://www.otherbit.com/modules/anobii/Styles/miniShelf.css');

Il codice JavaScript sopra, tramite loadStylesheet inietta lo stylesheet della weblet nella pagina ospite. handleResponse è la callback che prende il valore e lo copia nello spazio del DIV "cornice" (non c'è nemmeno da fare la docodifica JSON, lo fa già Dojo per noi). ajaxGET fa la chiamata alla dojo.io.script.get, ma prima carica nel DIV un messaggio di caricamento in corso. I valori passati a dojo.io.script.get sono:

  • l'url della funzione HTTP chiamata, senza la parte GET;
  • una struttura contenente i parametri GET da passare alla chiamata, incluso il nome della funzione di callback da usare nella formattazione JSONP
Infine, la chiamata dojo.require("dojo.io.script") di fatto rende disponibili le risorse Dojo impiegate nel codice e va fatta prima che entrino in funzione le chiamate a queste ultime, sennò Dojo non funziona.

Lato server, c'è da gestire il nuovo parametro GET con il nome della funzione di callback e da trasformare la chiamata JSON in JSONP impacchettando la nostra risposta codificata nella forma

<nome funzione di callback>(<output in forma JSON>);

ossia così

Response.Write(Request["callback"] + "(" +
    Jayrock.Json.Conversion.JsonConvert.ExportToString(output) + ");");
Response.End();
 

La storia finisce qui, anticipo che a breve renderò disponibile tutto il codice. Devo solo scorporarlo da quello di OtherWeb in una soluzione stand-alone, in modo che sia utilizzabile da coloro che ne fossero interessati.

 

data modifica 15-03-2010 07.25.29 GMT+02

#

Non ci sono commentiFeed RSS 2.0 di : Fuori programma, commenti a "La battaglia di aNobii (parte 4)"
Aggiungi un commento
Mittente : *
Email : 
Web : 
Testo del messaggio : * 
Codice di validazione : * 

otherbit, by Cosimo Carbonelli m. info@otherbit.com p.i. 11743080159
made with OtherWeb