A Short Guide to AJAX programming
First let's review how HTTP works to get web pages into the browser:
HTTP
When the web browser wants a page from a website, the following sequence ensues:
- The browser sends an HTTP (HyperText Transport Protocol) command over the Internet to the server containing the URL of the web page.
- The "httpd" (HTTP daemon) is "awoken" by the operating system and handed the URL. Most websites run "Apache" as their HTTP daemon - but there are others that work kinda similarly. I'm going to talk about Apache.
- What happens next depends on the filename extension:
- If there is no filename (eg "http://tubagames.net") then it changes it internally to "index.html" or "index.php".
- Most of the time (eg with an ".html" or ".css" or ".gif"/".png"/".jpg" file), Apache finds the file, sticks a special "header" on to the top of it - and sends it back to browser.
- If the "web page" that's requested has the ".php" extension, then Apache grabs the file - hands it to the PHP interpreter, which runs the program and hands the results to Apache...which passes it on to the browser. The PHP code essentially "prints out" the web page...but more complicated things are possible.
- If the "web page" is a ".cgi" file and is stored in a certain special "cgi-bin" directory (there are security issues here) then Apache runs it as a regular Linux program (probably written in C++ - but could be something else). Whatever the CGI program writes to the output (with 'printf' or 'cout <<...'). Apache takes whatever it outputs and sends it to the client.
- When the browser gets the resulting data, it looks for the "header" - and either displays it, or sets the style or whatever - depending on what the header tells it to do.
The "header" is pretty important because that's how the browser knows what to do with the file.
When Apache serves up a simple file (eg an HTML file or an image), it sticks a header on it that tells the browser what type it is based on the file extension. So for an HTML file, the header says:
Content-Type:text/html
...and the browser knows what to do with it. The "text/html" part is called the "MIME type"...which actually comes from email protocols...but that's another story. Aside from the standard MIME types - you can tell your browser to do things like running special plugins for particular MIME types...that's how the Flash plugin gets invoked when Apache sends the browser a flash file.
Parameters: GET and POST
GET
When you go to (say) Google and type in something into an HTML form, the resulting HTTP request contains an extended URL which has some extra "stuff" on the end (these are called "GET parameters":
http://www.google.com/index.html#q=helloworld
...everything after the "#" is a set of parameters separated by the "&" character. The example above sets the "q" (query? question?) parameter to the value "helloworld" - which Google obediently searches for. If you really do a Google search for "helloworld", it'll produce this kind of mess:
http://www.google.com/#sclient=psy&hl=en&q=helloworld&aq=f&aqi=&aql=&oq=&pbx=1&bav=on.2,or.&fp=bfd1057040a6822d
Which sets a BUNCH of parameters:
sclient=psy hl=en <== Searching in English q=helloworld <== We understand this one! aq=f aqi= aql= oq= pbx=1 bav=on.2,or. fp=bfd1057040a6822d
...who knows what all of those mean?!)
This data really only means something for PHP and CGI URL's. PHP and C++ "CGI" programs can read those parameters and do something different depending on what they are...Google clearly uses the value in the "q" parameter to determine what to search for.
This approach to sending data is called the "GET" method (I don't know why) and it's considered kinda old-fashioned.
In C++, the "GET" parameters are passed to the program on the command line - so you have to parse argc and argv to read them.
In PHP, there is an array called "$_GET[]" that's indexed by the parameter name and contains whatever parameters are passed this way. So if you were writing your own Google clone using PHP, you could say:
if ( isset ( $_GET ['q'] ) ) { $result = searchTheWebFor ( $_GET['q'] ) ; echo "Found these results:
" ; echo $result ; } else echo "Error: No search terms entered?" ;
POST
The "POST" method is more suited to PHP and CGI - but you have to send it from JavaScript code. In this method, the URL is just the name of the program you want to talk to. The data can be any ASCII text and it's sent to C++ on the standard input (so you can read it with "cin" or "scanf" or whatever). In PHP, it works the same way as "GET" except that the array is called "$_POST[]".
So here is a complete C++ CGI program:
#include <stdio.h> #include <stdlib.h> int main ( int argc, char **argv ) { char buffer [ 1024 ] = { 0 } ; fread ( buffer, 1024, 1, stdin ) ; printf ( "Content-Type:text/html\n\n" ) ; // IMPORTANT: DON'T CHANGE THIS LINE! printf ( "<HTML><HEAD></HEAD>\n" ) ; printf ( "<BODY>"\n" ) ;printf ( "
You typed:
" ) ;printf ( " %s\n", buffer ) ; printf ( "</BODY>\n" ) ; }
...if you call this (let's say) "echo.cpp", compile it on the server, place it into the "cgi-bin" directory with a ".cgi" file: "cgi-bin/echo.cgi"...then you can go to your browser and type in it's URL (complete with the ".cgi" extension) and you'll get back a web page that is a blank page with "You typed:" as an 'H1' heading. There won't be anything beneath that because we didn't send it any "POST" data.
For that, we need to make a web page with this form in it:
<form action="cgi-bin/echo.cgi" method="post"> Type something: <input type="text" name="something" /> <input type="submit" /> </form>
(Notice: 'method="post"', that invokes this method to sending data to the program, and 'action="cgi-bin/echo.cgi"' - which is the URL of the C++ program we wrote.)
Now you can type something into that text box - and whatever you type will go up to the server, the echo.cgi program will be run, it reads our input and prints out an HTML document with that text inside.
AJAX
So...finally...we're ready to talk about the "AJAX" thing. This uses the "POST" method to send data from the browser to the server and back again...exactly like we did above. But the difference here is that JavaScript code sends the command to the server - and JavaScript reads the result instead of the web browser itself.
Because JavaScript programs have to run quickly and then end - they can't hang around waiting for the round trip to the server. So you set up an "event" for the browser to call when the results come back.
First, create a global variable to hold the transaction information:
var http_request = new XMLHttpRequest () ;
...the original idea was to use this technique to fetch XML documents - but you can actually get any kind of data this way.
Then, you need to define a function that'll be called when the results arrive. Let's call it "updateFunc"...and we'll talk about what it does in just a moment.
When you want to talk to the server:
function sendToServer ( myData ) { http_request.onreadystatechange = updataFunc ; http_request.open ( "POST", "http:whatever.com/cgi-bin/echo.cgi", true ); http_request.setRequestHeader( "Content-type","application/x-www-form-urlencoded"); http_request.send ( myData ) ; }
...notice the name of our results gathering function "updateData" being set as the "onreadystatechange" event. Note that the full URL is passed on the second line, some "Content-type" header for the message (don't change this!) - and finally, we pass in the data - which actually causes the message to be sent.
The "updateFunc" function is called when the results are returned:
function updateFunc () { var ready = http_request . readyState ; if ( ready != 4 ) return ; var stat = http_request . status ; if ( stat != 200 ) return ;
var result = http_request . responseText ;
// ...do something with the result...
alert ( result ) ; // Pop up an alert box with the results in it. }
The system may call your "net_update" function several times - indicating various stages of progress before you actually have the message available. Hence the first two lines of the function check various status stuff and just return if there is a problem or if the message didn't actually arrive yet. When we finally get our answer, the "result" variable will be a string containing whatever the CGI or PHP program sent you.