Basis AJAX-les
Heb je je ooit afgevraagd hoe je jouw website een AJAX-verzoek uit kan laten voeren? Als je blijft lezen, kan je daarachter komen. Of, als je al ruime ervaring hebt, geen uitleg nodig hebt, maar gewoon de code wil zien, ga dan naar het voorbeeld (in het Engels) en bekijk de broncode. Je kan altijd nog terugkomen voor de uitleg.Het voorbeeld bij deze les zal, op de server, het commentaar van een bezoeker coderen, zonder de webpagina in de browser te verversen. Het mooie van het coderen uitvoeren op de server, is dat de opdrachten die voor de codering gebruikt worden voor de gebruiker verborgen blijven. Zij kunnen zien wat er IN gaat, wat er UIT komt, maar niet wat daartussenin gebeurt, wat het decoderen van de gecodeerde tekst veel moeilijker maakt. Laten we beginnen.
Zoals gezegd, we willen het commentaar van een bezoeker coderen. Laten we eerst een formulier aanmaken waar dat commentaar kan worden ingevuld. Dit is HTML op beginnersniveau:
Waarom "return false"? Simpel. Ik wil niet dat het formulier ook echt gesubmit wordt. Je ziet dat ik de knop verteld heb een specifieke actie uit te voeren als erop geklikt wordt. (onclick="codeer(); return false"). Als er op de knop wordt geklikt, wil ik dat de JavaScript-functie "codeer" zonder argumenten uitgevoerd wordt, en dat er dan wordt gestopt, zonder de standaardactie van de knop wordt uitgevoerd (het formulier submitten).
De "codeer"-functie maakt een XMLHTTP-object aan (deze voert het AJAX-request straks uit) en gebruikt deze om het gecodeerde commentaar op te halen. Om het XMLHTTP-object te verkrijgen, gebruikt het een andere functie, "maakAjaxObject". Hier is de volledige code voor beide functies, verderop wordt deze in detail uitgelegd:
-
<script type="text/javascript">
-
function codeer()
-
{
-
var oAjax = maakAjaxObject();
-
if (!oAjax)
-
{
-
alert('Kan geen XMLHTTP-object aanmaken. Je commentaar wordt niet gecodeerd.');
-
return;
-
}
-
-
var sUrl = "ajax_response.php?comment=";
-
var sCommentaar = document.getElementById('commentaar').value;
-
sUrl += escape(sCommentaar);
-
-
oAjax.open("GET", sUrl, true);
-
oAjax.send(null);
-
-
oAjax.onreadystatechange = function()
-
{
-
if (oAjax.readyState == 4 && oAjax.status == 200)
-
{
-
document.getElementById('gecodeerd').innerHTML = oAjax.responseText;
-
}
-
}
-
}
-
-
function maakAjaxObject()
-
{
-
var oAjax = false;
-
-
if (window.XMLHttpRequest)
-
{
-
oAjax = new XMLHttpRequest();
-
}
-
else
-
{
-
if (window.ActiveXObject) {
-
var aXmlHttpVersies = ["Msxml2.XMLHTTP.7.0", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0",
-
"Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP",
-
"Microsoft.XMLHTTP"];
-
-
for (var i = 0; i <aXmlHttpVersies.length; i++)
-
{
-
try
-
{
-
oAjax = new ActiveXObject(aXmlHttpVersies[i]);
-
-
if (oAjax) break;
-
}
-
catch (objException)
-
{
-
}
-
}
-
}
-
}
-
-
return oAjax;
-
}
-
</script>
Laten we deze code eens uitpluizen en kijken wat het doet. We beginnen met de "maakAjaxObject"-functie, omdat dat het eerste is dat wordt aangeroepen.
-
var oAjax = false;
Maak eerst een variabele oAjax aan, en stel deze in op false. Als alle manieren om een XMLHTTP-object aan te maken mislukken (dat komt zo), wordt deze variabele niet aangepast.
-
if (window.XMLHttpRequest)
-
{
-
oAjax = new XMLHttpRequest();
-
}
Als de standaardmethode voor het aanmaken van een XMLHTTP-object beschikbaar is, gebruik die dan. Dat zal in de meeste browsers werken, waaronder Mozilla, Netscape, Firefox, Safari, Opera en Internet Explorer 7. Voor oudere versies van Internet Explorer hebben we een andere manier nodig, en deze maakt gebruik van ActiveX. Eerst moeten we kijken of ActiveX wel beschikbaar is.
-
else
-
{
-
if (window.ActiveXObject) {
-
var aXmlHttpVersiss = ["Msxml2.XMLHTTP.7.0", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0",
-
"Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP",
-
"Microsoft.XMLHTTP"];
Als het mogelijk is om een ActiveXObject te maken, maak dan een array van Microsoft's ActiveX XMLHTTP objecten. Hier heb ik een hele goeie reden voor. Msxml2.XMLHTTP.7.0 is de meest recente versie die ik ken, die gebruikt kan worden om een XMLHTTP object aan te maken. Microsoft.XMLHTTP is de oudste. Zoals bij de meeste software, betekent een nieuwere versie dat deze beter werkt.
We gaan proberen een XMLHTTP-object te maken met de meest recente versie die beschikbaar is in de browser van de bezoeker. Om dat te doen, moeten we met een for-loop door alle items in de array gaan. We proberen een ActiveX object te maken met het huidige item in de aXMLHttpVersies-array, en we gaan uit de loop als het gelukt is een object aan te maken. Als ze allemaal mislukken, zal de loop vanzelf stoppen.
-
for (var i = 0; i <aXmlHttpVersies.length; i++)
-
{
-
try
-
{
-
oAjax = new ActiveXObject(aXmlHttpVersies[i]);
-
-
if (oAjax) break;
-
}
-
catch (objException)
-
{
-
}
-
}
De "if (oAjax) break;" zorgt ervoor dat we stoppen met door de array heen te lopen. Als er een probleem is met een (of meer) van de XMLHTTP objecten, kan dat voor een object exception zorgen. Deze hebben de gewoonte aan de gebruiker getoond te worden, op zijn minst met een geen driehoekje in de hoek linksonder van het browservenster. Tenzij we ze afvangen en er niets mee doen. Daar is de lege "catch (objException)"-functie voor.
Helemaal aan het eind van de functie geven we de oAjax-variabele terug. Als er een XMLHTTP-object is gemaakt, via XMLHttpRequest of een van Microsoft's ActiveX-objecten, zal deze variabele dat object bevatten. Als allebei deze methoden mislukt zijn, is de variabele nog steeds false, omdat dat de beginwaarde was toen we hem aanmaakten.
Nu gaan we kijken naar de "codeer"-functie, en wat we met het zojuist gemaakte XMLHTTP-object moeten doen om een verzoek uit te sturen, en een antwoord terug te krijgen.
-
var oAjax = maakAjaxObject();
-
if (!oAjax)
-
{
-
alert('Kan geen XMLHTTP-object aanmaken. Je commentaar wordt niet gecodeerd.');
-
return;
-
}
Maak allereerst gebruik van de maakAjaxObject-functie om een XMLHTTP-object aan te maken. Als dat mislukt (of als de functie false teruggeeft), geef dan een waarschuwing dat het object niet aangemaakt kon worden, en stop met het uitvoeren van de functie.
-
var sUrl = "ajax_response.php?comment=";
-
var sCommentaar = document.getElementById('commentaar').value;
-
sUrl += escape(sCommentaar);
We hebben een URL nodig om het verzoek naartoe te sturen. Voor dit voorbeeld heb ik een bestand ajax_response.php gemaakt, en deze vereist een parameter "comment". Deze comment is de waarde die gecodeerd moet worden. Deze zullen we uit het textarea moeten halen, en deze heeft het ID "commentaar". Omdat dit commentaar allerhande rare tekens kan bevatten, moeten we deze escape'n, zodat deze veilig achter de URL geplakt kan worden. Dat escape'n doen we in dezelfde stap als we hem achter de URL plakken.
-
oAjax.open("GET", sUrl, true);
-
oAjax.send(null);
Hier openen we eerst een nieuwe verbinding, waarbij we een GET-verzoek op de URL uitvoeren. De "true" daar betekent dat het verzoek "asynchroon" (de eerste A in AJAX) wordt uitgevoerd. Dit is allemaal onderdeel van het HTTP-protocol, dus we zouden ook een POST-verzoek kunnen uitvoeren. Het grote verschil tussen de twee is dat een GET-verzoek alle variabelen in de URL zelf heeft, terwijl een POST-verzoek alle variabelen in de inhoud van het verzoek heeft. Omdat dit een GET-verzoek is, hoeven we geen inhoud mee te sturen, dus zenden we een null-waarde. Als dit een POST-verzoek zou zijn, was onze URL "ajax_response.php" geweest, en zou de oAjax.send "comments=(het ge-escape'te commentaar)" zijn in plaats van "null".
-
oAjax.onreadystatechange = function()
-
{
-
if (oAjax.readyState == 4 && oAjax.status == 200)
-
{
-
document.getElementById('gecodeerd').innerHTML = oAjax.responseText;
-
}
-
}
Het XMLHTTP-object heeft een ingebouwde functie genaamd onreadystatechange. Deze wordt iedere keer dat de status van het XMLHTTP-object verandert uitgevoerd. Hier zeggen we wat er moet gebeuren als die functie wordt aangeroepen.
Als de readyState van het object gelijk is aan 4 ("voltooid"), en de status is gelijk aan 200 ("OK"), houdt dat in dat het object klaar is met het laden van het antwoord. Als dat zo is, moet het HTML-element met het ID "gecodeerd" bijgewerkt worden door de inhoud te overschrijven met de responseText van het XMLHTTP-object. De responseText is de waarde die we hebben teruggekregen van het script op de server.
Voor meer informatie over het XMLHttpRequest-object raad ik de Apple Developer Connection website aan, op http://developer.apple.com/internet/webcontent/xmlhttpreq.html.
Zo, we hebben nu het complete client-side script gezien. Maar wat gebeurt er nou eigenlijk aan de serverkant? Nou, in mijn geval is dat een PHP-script.
-
<?php
-
-
-
?>
Op de serverkant kan je doen wat je wil, maar zorg er wel voor dat je de tekst die je terug wil sturen naar de oorspronkelijke pagina (waar het XMLHTTP-object de responseText-waarde gebruikt) in de uitvoer van het script zet. Dat houdt in, dat als je met de hand in de adresbalk van je browser de URL invult (ervanuitgaande dat je met een GET-verzoek werkt), je de exacte uitvoer moet zien die je terug wil sturen naar de oorspronkelijke pagina.
Het voorbeeld van deze les (in het Engels) staat hier.
