login  Naam:   Wachtwoord: 
Registreer je!
 Tutorials

Tutorials > AJAX


Gegevens:
Geschreven door:
bosgroen
Moeilijkheidsgraad:
Moeilijk
Hits:
19305
Punten:
Aantal punten:
 (4.25)
Aantal stemmen:
12
Stem:
Niet ingelogd
Nota's:
 Lees de nota's (18)
 

Tutorial:

[AJAX] Wegwijs In De Basistechnieken

1. Inleiding
2. Asynchrone communicatie
3. Het XMLHttpRequest object
4. Data verzenden
4.1 Data verzenden: GET met het XMLHttpRequest object
4.2 Data verzenden: POST met het XMLHttpRequest object
4.3 Data verzenden: het event
5. Support voor niet-AJAX gebruikers
6. Data ontvangen
6.1 Data ontvangen: XHTML
6.2 Data ontvangen: niet opgemaakte tekst
6.3 Data ontvangen: XML
6.4 Data ontvangen: JSON
7. Een bestand uploaden
8. Tips
9. Voorbeelden
9.1 Voorbeeld 1: Een poll-systeem via AJAX
10. Conclusie

1. Inleiding

AJAX is hot! Sommigen noemen het een hype, anderen zien er de fantastische mogelijkheden van in. De techniek vormt de basis voor grote interactieve webapplicaties zoals bijvoorbeeld gmail. De techniek zorgde voor zo'n gebruikersgemak dat concurrenten Yahoo en Microsoft (live) iets gelijkaardigs uit de grond stampten. Voor het maken van zo'n grote webapplicatie kan je beter een AJAX-framework gebruiken. Wil je slechts enkele eerder kleine, eenvoudige AJAX-elementen in een site, dan is het niet aangeraden zo'n heel framework te laden. Gebruik dan liever één van de hier besproken technieken.

"What's in a name? That which we call a rose by any other name would smell as sweet." prachtige woorden van de schrijver Shakespeare, maar oh zo van toepassing voor het acroniem AJAX. Jesse James Garrett bedacht de naam AJAX in de douche als afkorting voor Asynchronous JavaScript and XML. Maar vandaag de dag is de term een begrip dat veel meer omvat. Gaandeweg werd duidelijk dat XML absoluut geen vereiste is om asynchrone communicatie met de server te verwezenlijken. Gewone XHTML, JSON of wat dan ook is minstens even goed. Bij een goeie implementatie is het resultaat bij de gebruiker identiek. Ook het befaamde XMLHttpRequest is eigenlijk ook geen absolute vereiste, dezelfde effecten kunnen bijvoorbeeld met verborgen iframes worden verkregen. Deze tutorial probeert je wegwijs te geven in de verschillende AJAX-technieken.


pijl top
2. Asynchrone communicatie

AJAX voor mij is een techniek die toelaat om 'op de achtergrond' te communiceren met de server (asynchroon). Bijgevolg moet geen pagina herladen te worden om informatie op te halen van en/of data op te sturen naar de server. Bij een goeie implementatie kunnen de laadtijden, die het internet de bijnaam World Wide Wait gaven, sterk verminderd worden. Bijgevolg zal de ongeduldige surfer zo'n website op technisch vlak verkiezen boven een andere.
Bij gmail bijvoorbeeld, biedt de AJAX-techniek heel wat voordelen bij het schrijven van een nieuw e-mail bericht. Terwijl je jouw e-mail aan het uittypen bent wordt op de achtergrond jouw bijlage al doorgestuurd naar de server. Handig, want zo zal je bij het effectief verzenden van het e-mail bericht niet moeten wachten totdat je MB's grote bijlage is geüploaded.
Maar ook op een kleine site is asynchrone communicatie interessant. Zo voor het stemmen op een poll. Is het echt nodig dat de hele pagina hiervoor wordt herlaad?
In discussies over AJAX komt vaak naar voren dat door deze asynchrone communicatie de site niet geïndexeerd kan worden door zoekmachines. Voor mij is dit nog nooit een probleem geweest, daar ik AJAX gebruik voor kleine interactieve functies die helemaal niet mogen geraadpleegd worden door een zoekmachine. Een zoekmachine heeft geen stemrechten op mijn pollsysteem en heeft niets te zoeken in een webgebaseerde e-mailclient zoals gmail.


pijl top
3. Het XMLHttpRequest object

De meeste AJAX-applicaties gebruiken het XMLHttpRequest-object als kern om asynchroon te communiceren met de server. Dit object is als native code aanwezig in Firefox, Opera, Safari, IE7,… Ook oudere IE-versies bieden ondersteuning, maar dit via tragere ActiveX-objecten zoals Msxml2.XMLHTTP.

De meeste ontwikkelaars gebruiken een standaard functie om het object te initialiseren, hieronder probeer ik het met behulp van een nieuw (virtueel) object.
<script> 1 var SERVER = { 2 loaded : false, 3 requestobj : false, 4 load : function() { 5 if( SERVER.loaded == false ) { 6 this.loaded = SERVER.loadrequestobj(); //probeer te laden 7 } 8 return this.loaded; 9 }, 10 loadrequestobj : function () { 11 if (window.XMLHttpRequest){ // if Mozilla, Safari etc or IE7 12 this.requestobj = new XMLHttpRequest(); 13 if (this.requestobj.overrideMimeType) this.requestobj.overrideMimeType('text/xml'); 14 return true; 15 } 16 else if (window.ActiveXObject){ // if IE, not IE7 17 try { 18 this.requestobj = new ActiveXObject("Msxml2.XMLHTTP"); 19 } 20 catch (e) { 21 try { 22 this.requestobj = new ActiveXObject("Microsoft.XMLHTTP"); 23 } 24 catch (e) { 25 return false; 26 } 27 } 28 return true; 29 } 30 return false; 31 } 32 }
Door SERVER.load() aan te roepen, zal SERVER.requestobj bevolkt worden met het best beschikbare httprequest-object, de functie zal bovendien false teruggeven indien er geen httprequest-object kon geladen worden.


pijl top
4. Data verzenden

4.1 Data verzenden: GET met het XMLHttpRequest object

Een GET-request via het httprequest-object bestaat typisch uit drie delen. Vooraleerst wordt de verbinding geïnitialiseerd met open. Bij GET wordt de data uiteraard in de url gestopt. Daarna wordt eventueel een callback-functie gedefinieerd met onreadystatechange. Ten laatste wordt de request uitgevoerd met behulp van send.

We breiden ons SERVER-object uit met een functie voor de afhandeling van GETrequests.
<script> 1 var SERVER = { 2 loaded : false, 3 requestobj : false, 4 load : function() { 9 }, 10 loadrequestobj : function () { 31 }, 32 GETrequest : function(url,data,func) { 33 if( !this.load() ) return false; 34 this.requestobj.open('GET', url+'?'+data, true); 35 if( func ) this.requestobj.onreadystatechange = func; 36 this.requestobj.send(null); 37 return true; 38 } 39 }
Nu we een functie hebben voor de afhandeling van GETrequest, kunnen we er makkelijk GETrequests uitvoeren als volgt:
SERVER.GETrequest( 'verwerk.php', 'doe=iets' );

Bij GET is het belangrijk op te merken dat IE de gewoonte heeft ook GET-requests te cachen. Je kan dit tegengaan door expliciet via php in de headers te melden dat op geen enkele manier de pagina mag gecached worden. Ook kan je bij de javascript-request erop letten dat er geen gecachede-pagina zal gebruikt worden door:
a) een randomgetal toe te voegen aan de request-url:
XMLHttpRequest.open( 'GET', url+'?'+data+'rid=' + Math.random() );
b) de If-Modified-Since header te gebruiken
XMLHttpRequest.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" ); //datum in het verleden


pijl top
4.2 Data verzenden: POST met het XMLHttpRequest object

Een POST-request via het httprequest-object is iets ingewikkelder dan de GET-versie. Opnieuw wordt de verbinding geïnitialiseerd met open, maar de data wordt nu niet in de url gestopt maar gevoed aan de send. Het is ook belangrijk dat we in de headers melden dat er nog POST-data volgt in de request, dit doen we met setRequestHeader.

Net zoals we gedaan hebben voor GETrequest, zullen we ons SERVER-object uitbreiden met een functie voor de afhandeling van POSTrequests.
<script> 1 var SERVER = { 2 loaded : false, 3 requestobj : false, 4 load : function() { 9 }, 10 loadrequestobj : function () { 31 }, 32 GETrequest : function(url,data,func) { 38 }, 39 POSTrequest : function(url,data,func) { 40 if( !this.load() ) return false; 41 this.requestobj.open('POST', url, true); 42 if( func ) this.requestobj.onreadystatechange = func; 43 this.requestobj.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 44 this.requestobj.setRequestHeader("Content-length", data.length); 45 this.requestobj.setRequestHeader("Connection", "close"); 46 this.requestobj.send(data); 47 return true; 48 } 49 }


pijl top
4.3 Data verzenden: het event

Je zal de data pas verzenden op een bepaald moment, een event dus.

Dit kan bijvoorbeeld zijn bij het klikken op een link. Je kan dit op twee manieren realiseren, hieronder geïllustreerd: ofwel met het onclick-attribuut ofwel binnenin het href-attribuut door gebruik te maken van het code woordje 'javascript:'. (Beide mogelijkheden hebben een identiek resultaat.)
<a onclick=”SERVER.GETrequest( ‘verwerk.php’, ‘letter=c’ );”>ajax-request (stuur letter c door naar server)</a> <a href=”javascript: SERVER.GETrequest( ‘verwerk.php’, ‘letter=c’ );”> ajax-request (stuur letter c door naar server)</a>

Bij forms zal je vaak gebruik maken van speciale formevents. Een typische is het onchange-attribuut horende bij een formelement. Zo zal iedere verandering aan de inhoud van het formelement onmiddellijk worden doorgestuurd naar de server.
<form name="ajax-formke"> <input type="text" name="letter" id="letter" value="" onchange="SERVER.GETrequest( 'verwerk.php', 'letter='+this.value );" /> </form>
Het javascript-woordje 'this' leidt enkel binnen het formelement tot een goed resultaat. Het uitgebreidere en altijd toepasbare DOM-navigatiesysteem luidt:
var waarde = document.forms['ajax-formke'].elements['letter'].value
Er dient ook opgemerkt te worden dat bij inputvelden altijd gebruik moet gemaakt worden van de javascriptfunctie: encodeURIComponent()
var data = 'id=5&letter='+waarde;
Gesteld dat de gebruiker in het inputveldje het volgende intypt 'c&id=4', dan zal jouw scriptje tot bizarre resultaten leiden: $_GET['letter'] zal 'c' bevatten en $_GET['id'] zal 5 of 4 bevatten. Dit is een vaak voorkomend probleem daar gebruikers in velden waar ze hele teksten kunnen intypen vaak karakters zoals & = willen gebruiken. Deze karakters moeten geëncodeerd worden alvorens toegevoegd aan de url.
var data = 'id=5&letter='+ encodeURIComponent(waarde); //data: id=5&letter= c%26id%3D5
PHP zal bij ontvangst automatisch decoderen en $_GET['letter'] zal 'c&id=5' bevatten, de effectief ingevulde tekst.


pijl top
5. Support voor niet-AJAX gebruikers

Er zijn natuurlijk nog steeds browsers op de markt die AJAX niet ondersteunen maar deze worden eigenlijk bijna niet gebruikt. Veel meer browsers zijn er waarin de gebruiker Javascript heeft uitgeschakeld of waar het XMLHttpRequest object is uitgeschakeld. Sommige gebruikers doen dit omdat ze denken dat dit gevaren kan inhouden. Slechte en onvolledige informatie is vooral de oorzaak van deze schrik voor een nuttige en krachtige technologie. De ontwikkelaar moet beslissen of hij voor deze relatief kleine groep een alternatief wil voorzien.

Een wijze om deze gebruikers toch dezelfde functionaliteit te bieden, heb ik hieronder geïllustreerd:
Door de functie een true te laten retourneren zal de url geladen worden, door een false te retourneren zal enkel het javascriptje worden uitgevoerd.
<a href="no-ajax.php?stem=5;javascript: return ajax_stem(5);">link</a> <script> Function ajax_stem( getal ) { if( !SERVER.load() ) return true; //tlukt niet met ajax, voer die url uit if( SERVER.GETrequest( 'verwerk.php', 'stem='+getal ) ) return false; //voer die url NIET uit } </script>


pijl top
6. Data ontvangen

Telkens de readyState van de aanvraag verandert, zal de browser de functie gekoppeld met behulp van onreadystatechange uitvoeren. readyState kan in principe de waarden 0 (uninitialized), 1 (open), 2 (send), 3 (receiving) en 4 (loaded) hebben. De browsersupport voor al deze getallen is echter verschillend, die voor 4 is gelukkig wel universeel.
Wie het nodig acht kan ook de status controleren. Met status krijg je de http-statuscode terug; 200 indien succesvol, 404 indien bestand niet werd gevonden,... Met statusText krijg je de tekst horende bij het getal.
Met responseText krijg je de respons in een string. Met responseXML krijg je de respons als een XML-document-object.

Gebruik je veel AJAX op jouw site, dan kan het handig zijn het SERVER-object uit te breiden met een ontvangst-functie.
<script> 1 var SERVER = { 2 loaded : false, 3 requestobj : false, 4 load : function() { 9 }, 10 loadrequestobj : function () { 31 }, 32 GETrequest : function(url,data,func) { 38 }, 39 POSTrequest : function(url,data,func) { 48 }, 49 Ontvangst : function() { 50 if( this.requestobj.readyState != 4 ) return false; 51 else if( this.requestobj.status != 200 ) return 'Fout: '+this.requestobj.statusText; 52 else return this.requestobj.responseText; 53 } 54 }
In de functie gedefiniëerd met onreadystatechange, kunnen we met behulp van de net opgestelde functie makkelijk de ontvangst controleren. Toepassingswijze:
var data = SERVER.Ontvangst();
if( data ) {
...iets doen met de data...
}



pijl top
6.1 Data ontvangen: XHTML

De meest eenvoudige manier om data terug te sturen en af te beelden is in vele gevallen ook de beste. De server kan xhtml uit een bepaald bestand terugsturen of er kan xhtml met een (bv php-)script gegenereerd worden, zoals men gewend is van de opbouw van een gewone pagina.
In het voorbeeldje hieronder zullen we de ontvangen xhtml toevoegen aan een div met de functie innerHTML. We doen dit op een reeds op voorhand bepaalde plaats in het document met behulp van een id, met de functie getElementById().
<script> 1 var SERVER = { 54 } </script> <script> 1 function zend( letter ) { 2 SERVER.GETrequest( 'verwerk.php', 'letter='+letter, doe ); 3 } 4 function doe( ) { 5 var data = SERVER.Ontvangst(); 6 if( data ) { 7 document.getElementById( 'divke' ).innerHTML = data; 8 } 9 } </script> <div id="divke"> <a href="javascript: zend( 'c' );"> ajax-request (stuur letter c door naar server)</a> </div>
Bovenstaande scriptje zal bij het klikken op de link, de link vervangen door de data die het ontvangt van de pagina verwerk.php?letter=c.


pijl top
6.2 Data ontvangen: niet opgemaakte tekst



pijl top
6.3 Data ontvangen: XML



pijl top
6.4 Data ontvangen: JSON

In tegenstelling tot het XML-formaat is JSON moeilijker leesbaar door een mens. Voordelen van het JSON-formaat is zijn compactheid en makkelijke verwerking. JSON is zo makkelijk te gebruiken doordat het eigenlijk javascript is, vandaar de naam Javascript Object Notation. Alle browsers ondersteunen dit formaat.
Om JSON terug te sturen naar de gebruiker vanaf de server, moet de server deze taal kunnen opstellen. Sinds PHP5.2 zijn er JSON-functies standaard ingebouwd als extensie. Wie een nog oudere php-versie gebruikt moet niet wanhopen, een script om JSON te gebruiken in php vind je hier. (je hebt pear hiervoor niet nodig, gewoon het bestandje json.php uploaden naar jouw server)

Stel we hebben een array met data in php (bv opgehaald uit de database) en we willen die data versluisen naar ons javascriptje. JSON is zeker en vast de makkelijste manier om dit te verwezenlijken. (We doen het hier op de niet PHP5.2-wijze maar via het aparte scriptje dat je hiervoor moet uploaden naar jouw server.)
<?php $ledenarray = array( array('naam'=>'jan','geslacht'=>'man'), array('naam'=>'wim','geslacht'=>'man') ); include_once( 'json.php' ); $json = new Services_JSON(); $output = $json->encode($ledenarray); echo $output; die(); ?>
Zo, de array werd geoutput in JSON-formaat. Nu moeten we enkel nog de data ontvangen in ons javascriptje en de data toewijzen aan een javascriptvariable.
<script> 4 function doe( ) { 5 var data = SERVER.Ontvangst(); 6 if( data ) { 7 eval( "var ledenarray = "+data ); //...vanalles doen met de data in de variable ledenarray 8 } 9 } </script>
Zo, we hebben data (uit een phparray) van de server gehaald en geladen in een javascriptarray zonder een pagina te refreshen.


pijl top
7. Een bestand uploaden

Een bestand met behulp van AJAX doorsturen is niet zo evident. Je zou het bestand moeten laden, omzetten met behulp van een soort base64encode-functie en als data in een POST-request voeren. De makkelijkste oplossing is waarschijnlijk niet met het XMLHttpRequest-object te werken maar met verborgen iframes.


pijl top
8. Nuttige Tips

- In javascript programmeren zonder debugger is bijna niet mogelijk. Zelf ben ik erg tevreden over de Firebug-plugin voor Firefox. In de console komt duidelijk tot uiting waar een fatale fout plaatsvindt, wat de request en response is van een xmlhttpobject,...


pijl top
9. Voorbeelden

Op aanvraag werden in deze tutorial enkele voorbeelden gestoken.
In de voorbeelden wordt vooral nadruk gelegd op het AJAX-gedeelte. Voor het server-side-gedeelte wordt de werkwijze verkort uit de doeken gedaan (dit is een tutorial geen copy-paste-script)!


pijl top
9.1 Voorbeeld 1: Een poll-systeem via AJAX

Als eerste voorbeeldje behandel ik een heel eenvoudige implementatie van een pollsysteem. Er wordt voor dit pollsysteem AJAX gebruikt omdat er zo geen pagina-refresh nodig is om een stem uit te brengen. De poll kan makkelijk op elke pagina van de site worden ingevoegd en er kan gestemd worden zonder dat afgeweken wordt van de pagina die de gebruiker op dat moment aan het bekijken is.

Het pollsysteem is eigenlijk niets meer dan een uitbreiding op 6.1.
pagina.php:
<script> 1 var SERVER = { 54 } </script> <script> 1 function poll_zend( poll_id, keuze_id ) { 2 SERVER.POSTrequest( 'poll_verwerk.php', 'poll_id='+poll_id+'&stem='+keuze_id, poll_doe ); 3 document.getElementById( 'polldivke' ).innerHTML = "<img src="loading.gif" />"; 4 } 5 function poll_doe( ) { 6 var data = SERVER.Ontvangst(); 7 if( data ) { 8 document.getElementById( 'polldivke' ).innerHTML = data; 9 } 10 } </script> <div id="polldivke"> <?php include_once( 'functions.php' ); $poll_id = 5; if( isset($_COOKIE['poll'.$poll_id]) ) { echo output_poll_resultaat( $poll_id ); } else { echo output_poll_stemformulier( $poll_id ); } ?> </div>
Tegenover 6.1 heb ik de zend-functie uitgebreid zowat er twee variabelen kunnen doorgestuurd worden: een poll_id en de gestemde keuze. Het lijntje 3 is helemaal nieuw, na het stemmen en voordat het resultaat van de poll ontvangen wordt, laten we de gebruiker weten dat zijn stem wordt verwerkt door een loading-figuurtje af te beelden. Zo'n figuurtjes kan je hier downloaden. Voor een goeie werking is het aangeraden zo'n figuurtjes te preloaden (ik doe dit door het figuurtje in een verborgen div te zetten).

Hierboven staat ook reeds een deeltje server-side-script in php. We kijken op het cookie met 'poll5' bestaat, indien ja heeft de gebruiker reeds gestemd en wordt het resultaat afgebeeld, indien niet geven we hem het stemformulier. Hiervoor worden functies gebruikt die in het bestand functions.php staan.
functions.php: (vereenvoudige versie)
function output_poll_resultaat( $poll_id ) { //We halen de pollresultaten op uit de database $sql = 'SELECT .... WHERE poll_id = '.(int)$poll_id; //We verwerken de databasegegevens tot xhtml return <<<EOF Keuze 1 (..%)<br /> Keuze 2 (..%)<br /> Keuze 3 (..%)<br /> EOF; } function output_poll_stemformulier( $poll_id ) { //We halen de pollmogelijkheden op uit de database //We verwerken alles en geven wat xhtml terug $s = ""; $s .= '<a href="javascript: poll_zend( '.$poll_id.', 1 );">Keuze 1</a><br />'; $s .= '<a href="javascript: poll_zend( '.$poll_id.', 2 );">Keuze 2</a><br />'; $s .= '<a href="javascript: poll_zend( '.$poll_id.', 3 );">Keuze 3</a><br />'; return $s; }

Zo, alles kan afgebeeld worden. Nu hoeven we er enkel nog maar voor te zorgen dat er effectief kan gestemd worden. Client-side is dit reeds geregeld met javascript, nu nog server-side de stem opvangen en opslaan in de database.
In het javascriptje hebben we gedefiniëerd dat de stem moet verzonden worden naar poll_verwerk.php.
poll_verwerk.php: (vereenvoudige versie)
if( isset($_POST['poll_id']) && isset($_POST['stem']) ) { //controleer of de data goed werd ontvangen $poll_id = (int)$_POST['poll_id']; $stem = (int)$_POST['stem']; if( !isset($_COOKIE['poll'.$poll_id]) ) { //gebruiker nog niet gestemd //stem opslaan in de database $sql = 'UPDATE ...'; //cookie opslaan voor een jaar setcookie( 'poll'.$poll_id, 'gestemd', time()+60*60*24*356); } //de pollresultaten doorsturen naar de browser echo output_poll_nogtestemmen( $poll_id ); }

Zo, dat was totaal niet zo moeilijk hé. Alle javascript is aanwezig, de php en mysql moet je zelf aanpassen aan jullie systeem.
In dit voorbeeld is duidelijk niet veel javascript gebruikt, het grootste deel van het script draait server-side.


pijl top
10. Conclusie

Gebruik AJAX voor meer gebruikersgemak. Maar doe niet mee aan de hype en gebruik het met mate. AJAX is een krachtige techniek, maar de implementatie is niet altijd zo makkelijk. Kies daarom de juiste techniek voor jouw toepassing.


pijl top

« Vorige tutorial : [AJAX] XMLHttpRequest object en live search

© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.016s