Mi capita sempre + spesso di parlare di AJAX e descriverlo come “facile da programmare” a persone che ancora non si sono avvicinate alla programmazione web avanzata. E’ ovvio che in questo caso non riesco ad essere molto credibile! :)
Quindi ecco qui una ppppiiiiccola guida passo passo per comprendere cosa veramente ci permette di fare questa nuova tecnologia. Credo che per leggere tutto senza fatica serva un minimo di conoscenza della programmazione web… o una bella fantasia! :P
Ah, per realizzare il tutto è necessario avere installati sulla propria macchina, o anche su una macchina remota, un server HTTP (io uso Apache 2.2) funzionante con PHP ed un server MySQL. Tutto open source naturalmente… basta scaricare ed installare! ;)
AJAX (Asynchronous Javascript and XML)… tutto si basa sul concetto di “comunicazione asincrona” con il server: noi clicchiamo su un link o un pulsante per eseguire un’azione su dei dati remoti (che possono essere righe di database, file sul disco del server, ecc…) e ne vediamo subito le conseguenze, ancor prima che le azioni siano comunicate al server.
Quindi, mentre noi andiamo avanti a navigare e a fare altro, un javascript si occupa (con molta tranquillità ) di comunicare al server l’azione che abbiamo eseguito “virtualmente”… sicchè il server capisce il da farsi ed esegue di fatto le azioni.
Il vantaggio? E’ stato eliminato il tempo di latenza della comunicazione client-server ed anche il reload della pagina! :)
Inoltre, sempre grazie ad AJAX, possiamo cambiare radicalmente il contenuto di una pagina web (tramite manipolazione DOM), richiedendo dati al server in formato XML o testo semplice, e sempre senza ricaricare la pagina… che per siti abbastanza complessi è una vera seccatura!
Andiamo al lato pratico della questione: il fondamento di AJAX è un oggetto javascript che si chiama XMLHttpRequest.
A causa delle differenti implementazioni sui diversi browser, questo oggetto viene creato tramite una funzione cross-browser che si scrive una volta e poi si può dimenticare tranquillamente. :)
function createXMLHttpRequest() {
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
try { return new XMLHttpRequest(); } catch(e) {}
alert("XMLHttpRequest not supported");
return null;
}
Quindi abbiamo capito che questa funzione restituisce il giusto oggetto per le chiamate AJAX, a seconda del browser. Cominciamo mettendola dentro un file di testo e chiamiamolo ajax.js.
Adesso dobbiamo decidere cosa fargli fare. Uhm… facciamo finta di avere una tabella in HTML con tante righe prese dal database sul server… e vogliamo che alla pressione di un pulsantino accanto alla riga, questa venga cancellata dalla pagina e anche dal DB.
Ovviamente la cancellazione “visuale” avverrà subito tramite manipolazione DOM e la cancellazione “reale” avverrà con i suoi tempi tramite una chiamata AJAX.
La parte che ci interessa della pagina HTML, cioè la tabella, potrebbe essere generata da un semplice script PHP, che non riporto. Nell’esempio successivo infatti realizzeremo questo passo in AJAX.
Ma andiamo alla nostra tabella. Nella pagina HTML, in mezzo a tutto il resto, avremo qualcosa del genere:
<html>
<head>
<title>Test AJAX 1</title>
<script type="text/javascript" src="ajax.js"></script>
</head>
<body>
<table id="tabella">
<tr id="riga_1">
<!-- QUESTO E' IL DATO PROVENIENTE DAL DB... -->
<td>Testo 1</td>
<!-- ...E QUESTO E' IL PULSANTINO DI ELIMINAZIONE -->
<td><input type="button" value="Elimina" onclick="elimina_riga(1)" /></td>
</tr>
<tr id="riga_2"> <!-- ALTRE RIGHE PER RENDERE LA COSA UN PO' VEROSIMILE -->
<td>Testo 2</td>
<td><input type="button" value="Elimina" onclick="elimina_riga(2)" /></td>
</tr>
<tr id="riga_3">
<td>Testo 3</td>
<td><input type="button" value="Elimina" onclick="elimina_riga(3)" /></td>
</tr>
</table>
</body>
</html>
… e la funzione Javascript (dentro il file ajax.js) che svolgerà l’azione sarà più o meno così:
function elimina_riga(id) {
// LA RIGA VIENE CANCELLATA DALLA PAGINA WEB
riga = document.getElementById("riga_"+id);
riga.parentNode.removeChild(riga);
// E ADESSO CANCELLIAMOLA _VERAMENTE_ DAL DB
var xhReq = createXMLHttpRequest();
xhReq.open("POST", "elimina_riga.php", true);
xhReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhReq.onreadystatechange = function() {
if (xhReq.readyState == 4) {
if(xhReq.status == 200) {
// PER SICUREZZA CONTROLLIAMO CHE L'AZIONE SIA ANDATA A BUON FINE
if(xhReq.responseText!="1") {
alert("Hey, qualcosa è andato storto!");
}
}
}
}
xhReq.send("id="+id);
}
Sul server ci sarà uno script elimina_riga.php che esegue l’azione asincrona sul database. Per completezza:
<?php
if(is_numeric($_POST['id'])) { // EVITIAMO ATTACCHI DI SQL INJECTION
mysql_connect('localhost', 'username', 'password'); // CONNESSIONE AL DB
mysql_select_db('database');
if(mysql_query("DELETE FROM tabella WHERE id=".$_POST['id']))
echo "1"; // ET VOILA'... RIGA CANCELLATA!
else
echo "0";
}
?>
Ho omesso tutti i controlli su un’eventuale autenticazione (che si potrebbe fare molto facilmente con le variabili di sessione del PHP), perchè è un argomento che non riguarda questo tutorial.
Beh… a questo punto il primo passettino con AJAX è stato fatto! :)
Adesso possiamo vedere qualcosa di più complicato… la richiesta di dati in formato XML!
L’XML è utile per organizzare i dati in una struttura ad albero schematica e allo stesso tempo flessibile dal punto di vista del programmatore.
Supponiamo di voler creare la tabella HTML dell’esempio precedente, utilizzando i dati presi dal database: la tabella sarà creata al carimento della pagina tramite una XMLHttpRequest e la manipolazione DOM del documento.
La pagina HTML dovrà associare all’evento di caricamento della pagina la funzione javascript per la creazione della tabella:
<html>
<head>
<title>Test AJAX 2</title>
<script type="text/javascript" src="ajax.js"></script>
</head>
<body onload="popola_tabella()">
<table id="tabella">
</table>
</body>
</html>
leggi_tabella.php è uno script PHP lato server che produce il file XML che ci serve per popolare la nostra tabella:
<?php
header("Content-Type: text/xml");
echo "<?xml version="1.0" encoding="ISO-8859-15" standalone="yes"?>\n";
mysql_connect('localhost', 'username', 'password'); // CONNESSIONE AL DB
mysql_select_db('database');
?>
<tabella>
<?php
$query = mysql_query("SELECT id, testo FROM tabella");
while($riga = mysql_fetch_assoc($query)) {
?>
<riga id="<?=$riga['id']?>"><?=$riga['testo']?></riga>
<?
}
?>
</tabella>
Il risultato che avremo sarà come questo:
<?xml version="1.0" encoding="ISO-8859-15" standalone="yes"?>
<tabella>
<riga id="1">Testo 1</riga>
<riga id="2">Testo 2</riga>
<riga id="3">Testo 3</riga>
</tabella>
e servirà una funzione javascript per richiedere la pagina XML al server ed interpretarla per farla diventare codice HTML.
Dentro ajax.js avremo la funzione principale:
function popola_tabella() {
var xhReq = createXMLHttpRequest();
xhReq.open("POST", "leggi_tabella.php", true);
xhReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhReq.onreadystatechange = function() {
if (xhReq.readyState == 4) {
if(xhReq.status == 200) {
xml = xhReq.responseXML;
if(xml!=null) {
// INDIVIDUA L'ELEMENTO tabella NELLA PAGINA HTML
tabella = document.getElementById("tabella");
// ELEMENTO tabella NEL FILE XML
var xmlTabella = xml.getElementsByTagName("tabella")[0];
// TUTTE LE RIGHE DELLA TABELLA NEL FILE XML
var xmlRighe = xmlTabella.getElementsByTagName("riga");
for(i=0;i<xmlRighe.length;i++) { // PER OGNI RIGA....
xmlRiga = xmlRighe<i>;
// LEGGE L'ID DELLA RIGA
id = xmlRiga.getAttribute("id");
// LEGGE IL TESTO CONTENUTO
testo = xmlRiga.childNodes[0].nodeValue;
// CREA UNA NUOVA RIGA
riga = document.createElement("tr");
// IMPOSTA L'ID
riga.setAttribute("id","riga_"+id);
// CREA LA CELLA CON IL TESTO
cella1 = document.createElement("td");
cella1.innerHTML = testo;
// CREA LA CELLA CON IL PULSANTE ELIMINA
cella2 = document.createElement("td");
// CREA IL PULSANTE ELIMINA
elimina = document.createElement("input");
elimina.setAttribute("type","button");
elimina.setAttribute("value","Elimina");
elimina.onclick = function() { elimina_riga(id); };
// AGGIUNGE IL PULSANTE ELIMINA ALLA CELLA
cella2.appendChild(elimina);
// AGGIUNGE LE CELLE ALLA RIGA
riga.appendChild(cella1);
riga.appendChild(cella2);
// AGGIUNGE LA RIGA ALLA TABELLA
tabella.appenChild(riga);
}
}
}
}
}
xhReq.send("");
}
E’ da notare che il codice che viene scritto dopo xhReq.onreadystatechange = function() { è da trattare come una funzione separata, che viene invocata quando la virtual machine rileva un cambiamento dello stato della XMLHttpRequest. Ciò implica che non potremo accedere da questo codice alle variabili utilizzate all’interno della funzione chiamante.
… direi che abbiamo finito! :lol:
Bene! :) Adesso chi volesse approfondire potrebbe utilizzare questi piccoli esempi come base per costruire qualcosa di più complesso. Vi assicuro che quanto c’è di più difficile nella programmazione AJAX è stato trattato in questo tutorialino-ino-ino! ;)
Maggiori informazioni sulle funzioni per la manipolazione DOM le potete trovare facilmente su Google.
Sperando di essere stato utile a qualcuno… vi auguro buona programmazione! :D