Asynchronous HTTP request generation in JavaScript (AJAX)
A motivating example Suppose we have a table which was created like this create table cs4408demo (name varchar(60), url varchar(255)); Suppose we have a utility for adding entries to this table It might be implemented as on the next slide
Add Organization utility <?php if ( ($name) && ($url) ) { $db = mysql_connect("localhost","myUserName","myPassword"); mysql_select_db("stories",$db); $query = "select * from cs4408demo where name='$name'"; $result=mysql_query($query,$db); if ($row=mysql_fetch_array($result)) { echo "Organization already in database"; } else { $query = "insert into cs4408demo (name,url) values ('$name','$url')"; mysql_query($query,$db); echo "Data stored"; } } else {?> "> Name of organization: URL of organization's website: Store details in database <?php } ?>
The form looks like this
A completed form
If the organization is new, the data are stored in the database
If the organization is old, the data are rejected
When is the check made? In the above scenario, the user must fill in all the data on the form and submit the form before he learns that he is wasting his time
When would it be better to make the check? It would be better if the user could learn as soon as possible that he is duplicating data that are already in the database It would be better if could learn this while he is still filling in the form That is, we can the browser to check the database while the user is still filling in the form
Javascript HTTP Request objects Javascript provides an object class for making HTTP requests Unfortunately, it has two different names: –In Microsoft browsers it is implemented as an ActiveXObject class called Microsoft.XMLHTTP –In other browsers it is a Javascript object class called XMLHttpRequest()
What good are these Javascript HTTP objects? Suppose we had a separate PHP program which could be called to see if an organization is already in the database We could use a Javascript HTTP Request object to call this program –immediately after the user has filled in the organization's name on the form –and while he is still filling the rest of the form If the response to this request says the organization is already present, he could be warned alerted before he submits the form
The checkOrg.php program <?php $db = mysql_connect("localhost","myUserName","`myPassword"); mysql_select_db("stories",$db); $query = "select * from cs4408demo where name='$name'"; $result=mysql_query($query,$db); if ($row=mysql_fetch_array($result)) { echo "Organization already in database"; } else { echo "Organization is new"; } ?>
Example call
Another example call
We could use a Javascript HTTP Request object to call this program Then we could use a Javascript string search to see if the source code for the response page contains the word already or the word new If the response page contains the word already, we could alert the user that he is duplicating existing data
Example duplication warning
Improved utility for adding organizations to database It is here:
First part of program is unchanged Add Organization utility <?php if ( ($name) && ($url) ) { $db = mysql_connect("localhost","myUserName","myPassword"); mysql_select_db("stories",$db); $query = "select * from cs4408demo where name='$name'"; $result=mysql_query($query,$db); if ($row=mysql_fetch_array($result)) { echo "Organization already in database"; } else { $query = "insert into cs4408demo (name,url) values ('$name','$url')"; mysql_query($query,$db); echo "Data stored"; } }
Second part of program is changed else {?> "> Name of organization: URL of organization's website: Store details in database... This will be defined on next few slides... <?php } ?>
Second part of program (contd.) function check(name) { if (window.XMLHttpRequest) // Mozilla, Safari,... { http_request = new XMLHttpRequest(); } else if (window.ActiveXObject) // IE { http_request = new ActiveXObject("Microsoft.XMLHTTP"); } http_request.onreadystatechange = handleResponse; url=' http_request.open('GET', url,true); http_request.send(null); } function handleResponse() { if (http_request.readyState == 4) //response received { response=http_request.responseText; if (response.search('already') != -1) { alert('Organization already in database'); } } }
Second part of program (contd.) function check(name) { if (window.XMLHttpRequest) // Mozilla, Safari,... { http_request = new XMLHttpRequest(); } else if (window.ActiveXObject) // IE { http_request = new ActiveXObject("Microsoft.XMLHTTP"); } http_request.onreadystatechange = handleResponse; url=' http_request.open('GET', url,true); http_request.send(null); } function handleResponse() { if (http_request.readyState == 4) //response received { response=http_request.responseText; if (response.search('already') != -1) { alert('Organization already in database'); } } }
AJAX methods abort() Stops the current requestgetAllResponseHeaders() Returns complete set of headers (labels and values) as a string getResponseHeader("headerLabel") Returns the string value of a single header label open("method", "URL"[, asyncFlag[, "userName"[, "password"]]]) Assigns destination URL, method, and other optional attributes of a pending request send(content) Transmits the request, optionally with postable string or DOM object data setRequestHeader("label", "value") Assigns a label/value pair to the header to be sent with a request
AJAX Properties onreadystatechange Event handler for an event that fires at every state change readyState Object status integer: 0 = uninitialized 1 = loading 2 = loaded 3 = interactive 4 = complete responseText String version of data returned from server process response XMLDOM-compatible document object of data returned from server process status Numeric code returned by server, such as 404 for "Not Found" or 200 for "OK" statusText String message accompanying the status code
A "bug" in AJAX AJAX implementations appear to be over- eager to cache responses to requests In most cases, this does not matter In those cases where it causes a problem, this over-eager caching can be overcome by inserting a time-stamp into each request Example on next page
Preventing over-eager caching Suppose the JavaScript variable url already contains the web address and data we want to use in our request We can prevent caching problems by making each request unique, by giving each request a time-stamp Here is an example: now = new Date(); url = url+'&time='+now.getTime(); http_request.open('GET', url,true); http_request.send(null);