01. november 2006 - 12:56Der er
26 kommentarer og 1 løsning
Teoretisk spørgsmål om Ajax med JavaScript
Jeg sidder pt. og læser lidt tutorials omkring JavaScript og Ajax, bl.a. på javascriptkit.com. Har efterhånden fået ind i min lille knold, hvordan opretter et ajax object på en måde så det virker i både IE og andre browsere. Og forstår stort set også, hvordan man kan oprettet en funktion, så man kan få skrevet det tekst ud man får retur fra den fil man kalder. Men de funktioner jeg har kigget på, kan jeg kun få til at virke, i mit hoved, hvis den fil man kalder, lave hele html-koden, og altså ikke bare tilføjer teksten til eksisterende elementer som man kan med JavaScript, f.eks. med nodes osv.
Der hvor jeg godt ville hen var naturligvis, at man kaldte en side, typisk PHP, der kaldte en database og hentede noget info, hvorpå det blev tilføjet i et element (node), eller erstattede den gamle tekst i det element.
Jeg har set man kan kalde en php-fil via javascript, hvis man i php filen bare sørger for, at alt der bliver udskrevet, er javascript kode... Er det den vej rundt man skal gå?
Det er helt korrekt. Idéen med Ajax er netop at udveksle de rå data - formatere dem på klienten - og indsætte dem i dokumentet med DOM. HTML-formatering og brug af innerHTML har ikke meget med Ajax at gøre.
Du må først og fremmest vælge data-format og her kan du vælge mellem XML og JSON: http://www.json.org/
Personligt bruger jeg JSON, da det er lige til at anvende i JS, men det er en smagssag.
Det bliver nok en heftig mundfuld at lave Ajax-eksempler fra grunden i en tråd her, så jeg vil anbefale dig at søge efter tutorials på Google ... og måske, du kan komme lidt nærmere med denne side: http://developer.mozilla.org/en/docs/AJAX
Okay tak, jeg var heller ikke så meget ude efter komplekse eksempler, dem kan jeg lege lidt med selv, men læste på javascriptkit.com, at man kunne kalde en php side, i det tag man normalt kalder et eksternet javascript med, så tænkte om det var muligt:)
Ja, hvis det bare er nogle get-variabler, du skal sende til serveren og have svar på, kan du blot bruge et alm. script-element:
<script type="text/JavaScript"> function talk2server(q) { var o = document.getElementById("scriptLoader"); while (o.firstChild) o.removeChild(o.firstChild); // Slet evt. script-tags i div'et
var scr = document.createElement("script"); // Opret nyt script-element scr.setAttribute("type", "text/JavaScript"); scr.setAttribute("src", "http://www.domain.dk/mappe/fil.php?" + escape(q) + "&u=" + new Date().getTime());
Så kan du i PHP-filen 'www.domain.dk/mappe/fil.php' finde de tre variabler (var1, var2 og var3) i $_GET-array'et. Med dem kan du lave database-opslag m.m. og udskrive et JS-kald - ganske somom, der var tale om en alm. JS-fil :)
Når nu man har følgende stykke kode (hugget direkte fra javascriptkit.com): ========================== function HttpRequest(url){ var pageRequest = false //variable to hold ajax object /*@cc_on @if (@_jscript_version >= 5) try { pageRequest = new ActiveXObject("Msxml2.XMLHTTP") } catch (e){ try { pageRequest = new ActiveXObject("Microsoft.XMLHTTP") } catch (e2){ pageRequest = false } } @end @*/
if (!pageRequest && typeof XMLHttpRequest != 'undefined') pageRequest = new XMLHttpRequest()
if (pageRequest){ //if pageRequest is not false pageRequest.open('GET', url, false) //get page synchronously pageRequest.send(null) embedpage(pageRequest) } }
function embedpage(request){ //if viewing page offline or the document was successfully retrieved online (status code=2000) if (window.location.href.indexOf("http")==-1 || request.status==200) document.write(request.responseText) }
HttpRequest("external.htm") //include "external.htm" onto current page ========================== Hvor det er funktionen embedpage, der bliver kaldt hver gang den asynkrone forespørgsel's status ændres, skal man så i selve html/php koden på selve siden, blive ved med at kalde den funktion hvorefter den selv tjekker om status er ændret, eller kører den uafbrudt når man har kaldt den allerførste gang?
Jeg forstår ikke rigtig dit spørgsmål. Generelt kan man dog sige, at koden, du viser, ikke har ret meget med Ajax at gøre (faktisk strider det direkte mod principperne bag Ajax) =)
Fidusen ved Ajax er, at man kun udveksler rå data mellem server og klient. Data returneres fra serveren i XML- eller JSON-format (www.json.org og http://www.exp.dk/artikler/227).
På klienten formateres data som HTML ved at oprette elementer med DOM - fylde data i dem - og indsætte dem i dokumentet.
Desværre er der en del tutorials, der forvirrer mere end de gavner - idet de formaterer al HTML på serveren og indsætter dette i browser-dokumentet med 'innerHTML'. Men 'innerHTML' aldrig har været valid i nogen standard - og er helt uforlignelig med X(HT)ML :oP
Hehe okay, så i bund og grund gælder det om, at kalde en side, f.eks. php, der vha. en database eller noget andet på serveren, danner en XML-fil f.eks. (eller bare kalder en statisk XML-fil), hvorefter man så, i selve javascriptet, henter data fra den xml-fil det drejer sig om, og smider dem ind som nodes?
Yups ... og personligt foretrækker jeg at formatere mine data som JSON (JavaScript Object Notation), da det er mere enkelt at bruge direkte under JavaScript. Har du f.eks. et recordset serialiseret i en JSON-streng som denne:
var recSet = "{rows:[{user:'olebole', id:1234}, {user:'kongfjong', id:2345}, {user:'blabla', id:3456}]}";
- så konverterer du den tilbage til et objekt med eval på denne måde:
eval("var myObj = " + recSet);
Derefter har du objektet liggende i 'myObj' og kan f.eks. bruge det noget à la:
var o = oo = tx = null; var elm = document.getElementById("myContainerDiv"); for (var i=0; i<myObj.rows.length; i++) { o = document.createElement("div"); oo = document.createElement("a"); oo.setAttribute("href", "http://www.myDomain.dk/side.php?id=" + myObj.rows[i].id); tx = document.createTextNode(myObj.rows[i].user); oo.appendChild(tx); o.appendChild(oo); elm.appendChild(o); }
Ah yeah, smart egentligt:) JSON handler i bund og grund om de syntakser omkring objekt, arrays og values, right?
Og med dit eksempel drejer det sig så i bund og grund om, i princippet samme php fil, at kalde database, og alt hvad ma så foretager sig med den data, skal formuleres som javascript?
Nede i bunden af JSON-siden, jeg linkede til, kan du finde forskellige 'oversættere' mellem JSON og diverse server-sprog. Jeg kan specielt anbefale denne C-extension til PHP: http://www.aurore.net/projects/php-json/
Fordelen ved den første er, at den er ekstremt hurtig ... dramatisk meget hurtigere end nummer to!
Jeg har selv skrevet en lille, rimelig hurtig PHP-klasse, der ikke er så omfattende og 'røv-tørrende' (undskyld mit fransk), som nummer to i dette indlæg. Til gengæld er den rigelig sikker, hvis man ellers tænker sig lidt om og holder nogenlunde styr på sine data. Den ligger på min hjemmemaskine, men skal prøve at huske at lægge den på mp3-afspilleren i aften ... så kan jeg kyle koden efter dig i morgen =)
Men har jeg ret i, at hvis jeg vil have en div til hele tiden at bive opdateret, asynkront med resten af siden, lidt som når man simpelt med javascript, beder siden refreshe hver 5. sekund, skal kalde den funktion der sætter det hele i gang, som f.eks. makeRequest() funktionen i eksemplet på denne side: http://developer.mozilla.org/en/docs/AJAX:Getting_Started
løbende med f.eks. en setInterval i bunden af den funktion, så den kalder sig selv hver 5. sekund f.eks.?
Men hvorfor overhovedet gå igennem skridtet med at konvertere de data jeg henter fra db'en om til enten JSON eller XML format, for derefter at parse det i JavaScript, når jeg i en og samme PHP fil, kan hente dataene, og echo'e en masse javascript med de data i direkte?
Det er så lidt. Ajax er en fed teknik, som jeg gerne vil hjælpe andre til at forstå :)
Der er flere fordele ved at vælge et 'data-overførings-format' fremfor et egentligt markup-format (og ja, jeg ved godt, hvad XML betyder ... men alligevel! ;o)
F.eks. kan forskellige klienter hente fra samme 'feed' og formatere data til hvert sit formål - ligesom det er lettere at have med at gøre ved udvidelser, omlægninger, m.m ... vedligeholdelsen bliver ganske enkelt lettere. Derudover fylder data (specielt med JSON) væsentligt mindre end den tilsvarende HTML. Det giver mindre trafikforbrug og mindre resource-forbrug på serveren.
Men dvs. at hvis jeg nu kaldte den php-fil, som brugte dataen direkte, og echo'ede noget javascript-kode ud, ville det kræve flere kræfter af servere, end hvis jeg bare hentede noget data med php og formaterede det til xml/json, hvorefter det så blev behandlet af javascript?
Det giver ikke rigtigt mening i mit lille hoved, fordi jeg lave samme mængde handlinger hvad enten jeg echo'er noget javascript eller opretter xml-filer, som så bliver viderebehandlet af javascript, med min php...
En anden ting: Jeg kan se det for mig, hvordan jeg laver xml-filerne med php, sådan da, men med json kan jeg ikke rigtig. Og laver man egentligt xml/filer sådan rent fysisk eller hvordan?
For det første er det JSON-projekt, jeg linkede til, en ekstremt hurtig C-extension (hurtigere end de fleste XML-extensions) - og for det andet, fylder JSON-formaterede data mindre at sende end tilsvarende XML-formaterede.
Min egen JSON-encoder ser sådan ud (bemærk, at det er alm. PHP og dermed betydeligt langsommere end den, jeg linkede til tidligere):
<?php /*================================================*\ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ JSON-Encoder for AJAX ____________________________________________________ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Filename: jsonEncode.php (c) Copyright: Ole Clausen - 2006 --------------------- Free for use if this notice is left intact ____________________________________________________ \*================================================*/
function encPair($key, $val) { if (is_object($val)) { if ($key) $s = "\"".$key."\":".json_encode($val); else $s = json_encode($val); } else if (is_array($val)) { $a = array(); for ($i=0,$j=count($val); $i<$j; $i++) array_push($a, encPair(false, $val[$i])); if ($key) $s = "\"".$key."\":[".implode(",", $a)."]"; else $s = "[".implode(",", $a)."]"; } else if ($key) $s = "\"".$key."\":\"".$val."\""; else $s = "\"".$val."\""; return $s; } function json_encode($var) { $a = array(); foreach ($var as $x=>$y) array_push($a, encPair($x, $y)); return "{".implode(",", $a)."}"; }
include("jsonEncode.php"); $oJsOn = new JsOnObj(); // Opret et tomt objekt
// Forbind til database her
/* Dette er et eksempel på, hvordan du returnerer et record-set som JSON: $a = array(); $sql = "SELECT `id`, `username`, `age`, `sex` FROM `users`"; $res = mysql_query($sql); while ($row=mysql_fetch_object($res)) { $a[] = $row; } $oJsOn->rows = $a; */
$oJsOn->myVar = "Farseret gnupung med morkelsauce og syltede tidsler";
$oJsOn->colObj = new JsOnObj(); // Opret et tomt objekt $oJsOn->colObj->r = 255; $oJsOn->colObj->g = 255; $oJsOn->colObj->b = 0;
Hej ole, jeg tror jeg har fået nok teori nu:) Vil vente til jeg har et praktisk eksempel at bruge det på, så nu skal du bare smide et svar, så får du dine, velfortjente, point;)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.