What is XMLHttp?
Courtesy of 4guysfromrolla:
It is an object that was originally designed by Microsoft to provide client-side access to XML documents on remote servers through the HTTP protocol. It exposes a simple API which allows you to send requests (yes, even POSTS) and get the resultant XML, HTML or binary data!
It has since grown and is now available on most popular browsers using Javascript as a vehicle.
What can XMLHttp do for me?
A question that comes up on this forum consistently is, "how can I retrieve server side information without refreshing/reloading a page["
There are few answers and one that is little known about is XMLHttp. XMLHttp allows a browser to request a page from a server and return information to the loaded page without the necessity of refreshing/reloading the page. The information can then be placed into a javascript variable and handled on the currently loaded page.
Is XMLHttp slow?
when compared to the alternatives (flash, java applets etc), XMLHttp is probably a bit slower as there is not a persistent connection to the server from the client. The speed at which data is returned from the server also depends entirely on your connection to the web server. In other words, if you request a page normally and it takes 15 seconds for the server to respond (not load the page mind you...respond), the same would hold true for the XMLHttp object to return a response. I have used XMLHttp for chat applications, verifying form data (prior to form submission), updating database tables, etc and have been very pleased with the experience.
Is XMLHttp Ajax?
XMLHttp is the precursor to ajax and ajax actually uses XMLHttp to work. Understanding XMLHttp will significantly help you understand and consequently develop applications that are Ajax driven. For more information on Ajax alone, try googling it and you'll come up with a plethora of information.
Ok now to the goods:
We're going to use XMLHttp to generate a page for the imfamous "who's online" feature on a lot of web sites. Unlike most however, this will be a "realtime" check of people who are on your website at any given moment (within 30 seconds for the example).
The first step in using XMLHttp is to create the object so the browser has a method for establishing a connection to the server. I typically do this in a try/catch so that if it dies, I can still run other JS on my page:
Code: Select all
try{
if (window.XMLHttpRequest){ // check for firefox and other browsers
reqsend = new XMLHttpRequest(); // create object for ff and other browsers
}else{ // not firefox or the like...
reqsend = new ActiveXObject("e;Microsoft.XMLHTTP"e;); // create object for IE 5.0 or later (at least I think it's 5.0 ^o)
}
}catch(e){
};We're going to create a function that will be called on regular intervals to:
1) update the database to let it know that we're still online
2) fetch a list of users who are currently online
again, I put this in a try/catch block just in case, in the real world, you'd want to supply an alternative in case it fails...
Code: Select all
function updateIt(){
try{
reqsend.open("POST", "online.php", true); // here we set the request type, the page we're requesting and whether or not we want it to be asyncronous (true is asyncronous and is the default)
var stuff = "upd=1&who=<?=$_SESSION['loggedinid'];?>"; // here we set a string with the post vars...more on this later
reqsend.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); // because we're using POST, we need to set some headers...this is what took me a long time to figure out
reqsend.setRequestHeader("Content-Length",stuff.length); // we need to set the length of the amount of information we're sending and this is dynamic as it's based on the length of the stuff string var
reqsend.send(stuff); // next we actually send the information and perform our "request"
reqsend.onreadystatechange = function(){ // create a function that is called on a change (response received) from the server
if (reqsend.readyState == 4 && reqsend.status == 200) {
/* here we're looking to make sure the page has been fully loaded (complete) and that we did not receive an error from the server. The readyState options are as follows:
Object status integer:
0 = uninitialized
1 = loading
2 = loaded
3 = interactive
4 = complete
the status is just looking for the page status of the server ie: 404=page not found 500=internal server error 200=all is good, eat gravy etc...
*/
document.getElementById('namez').innerHTML = reqsend.responseText; // finally we need to update the page with the list of online users using innerHTML
}
};
}catch(e){
location = "online.php";
}
setTimeout("updateIt()",10000); // recall the function every 10 seconds
}That's all there is to it! Of course we need some php on the back end to query the database and send us responses and we need an html page to list all of those users:
This requires a table (called online here) with the following fields:
username -> varchar(255)
userid -> int
last -> datetime
this also assumes you have a couple session vars set, one with the username "loggedin" and one with the user id "loggedinid"
Code: Select all
<?
require_once("includes/dbConnect.inc.php"); // database connectivity stuff mysql_connect() etc
require_once("includes/session.inc.php"); // session stuff session_start() etc
if(!isset($_POST['upd'])){ // check to see if this is the first page load, or if it's coming from XMLHttp
mysql_query("update online set last = now() where userid = ".$_SESSION['loggedinid'])
or die("update death ".mysql_error()); // update the table for "returning users"
$tryupdate = mysql_affected_rows(); // check to see if it was a returning user
if(!$tryupdate != 0){
mysql_query("insert into online
(
username,
userid,
last
)
values
(
'".mysql_escape_string($_SESSION['loggedin'])."',
".$_SESSION['loggedinid'].",
now()
)")
or die("insert death ".mysql_error()); // insert a new row for non-returning users
} // end if for need to insert new row
} // end if for post upd set
$getnames = mysql_query("select * from online where last > '".date("Y-m-d H:i:s", time() - 30)."' order by username")
or die(mysql_error()); // get list of users who are online (within 30 seconds)
if(isset($_POST['upd'])){ //stuff below came from XMLHttp so work accordingly
mysql_query("update online set last = now() where userid = ".$_POST['who'])
or die(mysql_error()); //only need update here as they will have a record for sure based on the fact it was created when they entered the page
$nameslist = "";
while($gtnames = mysql_fetch_assoc($getnames)){
$nameslist .= addslashes($gtnames['username'])."<br>"; // generate list of names of people online
} // end while for result set
echo $nameslist;
exit;
} // end if for need to show update
?>Code: Select all
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Online</title>
<link rel="stylesheet" href="styles/style.css">
</head>
<body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" onLoad="updateIt()">
<div align="center">
<span id="namez"></span>
</div>
</body>
</html>here's the full code:
Code: Select all
<?
require_once("includes/dbConnect.inc.php");
require_once("includes/session.inc.php");
if(!isset($_POST['upd'])){
mysql_query("update online set last = now() where userid = ".$_SESSION['loggedinid'])
or die("update death ".mysql_error());
$tryupdate = mysql_affected_rows();
if(!$tryupdate != 0){
mysql_query("insert into online
(
username,
userid,
last
)
values
(
'".mysql_escape_string($_SESSION['loggedin'])."',
".$_SESSION['loggedinid'].",
now()
)")
or die("insert death ".mysql_error());
} // end if for need to insert new row...burrito
} // end if for post upd set...burrito
$getnames = mysql_query("select * from online where last > '".date("Y-m-d H:i:s", time() - 30)."' order by username")
or die(mysql_error());
if(isset($_POST['upd'])){
mysql_query("update online set last = now() where userid = ".$_POST['who'])
or die(mysql_error());
$nameslist = "";
while($gtnames = mysql_fetch_assoc($getnames)){
$nameslist .= addslashes($gtnames['username'])."<br>";
} // end while for result set...burrito
echo $nameslist;
exit;
} // end if for need to show update...burrito
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Online</title>
<link rel="stylesheet" href="styles/style.css">
<script>
try{
if (window.XMLHttpRequest){
reqsend = new XMLHttpRequest();
}else{
reqsend = new ActiveXObject("Microsoft.XMLHTTP");
}
}catch(e){
};
function updateIt(){
try{
reqsend.open("POST", "online.php", true);
var stuff = "upd=1&who=<?=$_SESSION['loggedinid'];?>";
reqsend.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
reqsend.setRequestHeader("Content-Length",stuff.length);
reqsend.send(stuff);
reqsend.onreadystatechange = function(){
if (reqsend.readyState == 4 && reqsend.status == 200) {
document.getElementById('namez').innerHTML = reqsend.responseText;
}
};
}catch(e){
location = "online.php";
}
setTimeout("updateIt()",10000);
}
</script>
</head>
<body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" onLoad="updateIt()">
<div align="center">
<span id="namez"></span>
</div>
</body>
</html>happy XMLHttp'ing