REMOTE SCRIPTING WITH COOKIES
FOR SMALL AMOUNTS OF DATA

By Peter A. Bromberg, Ph.D.

Peter Bromberg  

If you've had any experience with RDS, you know it can get pretty complicated. Remote Scripting (which uses a small Java applet) can often be a more lightweight solution. One of the best remote scripting solutions I've found is by Brent Ashley     http://www.ashleyit.com/ who calls his solution JSRS (Javascript Remote Scripting). He uses no Java Applet, only a hidden "Container" typically in an IFRAME, to receive the results of the server call into the client page. Ashley's solution is also cross-browser compatible.

While revisiting his page to see if there was anything new, I noticed a small post by the author about using cookies to do remote scripting. He had a few lines of code (not a full solution), but there was enough there to spark my curiosity. So I put together this lightweight Remote Scripting example to populate the City / State from a database call when you enter the ZipCode, a task that is probably pretty common in filling out forms on the web.



I've included an Access 97 database of all the zipcodes in the US for you as a little "Bonus" along with the code for the client and server pages in the example ZIP file which you can download below. So, you should be able to play with this idea "right out of the box". You should find this an extremely lightweight solution for getting small amounts of data back from the server in an "in-memory" cookie that doesn't even get written to the filesystem. With only minor modification, this should be able to be made to work with Netscape browsers, if you are so inclined.

First, let's look at my code for the server page:

<%
' "ProvideCookieRS.asp"

parm = Request("p")
if len(parm) < 5 then
Response.Cookies("RSCookie")=" "
else
Response.Cookies("RSCookie") = processParm( parm )
end if
Response.End

Function processParm( parm )
set rs = server.createObject("ADODB.Recordset")
conn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & server.mappath("zipcodes.mdb") & ";"

strSQL ="Select city,state from zipcodes where zip ='" & parm & "'"
rs.Open strSQL , conn
if (rs.BOF and rs.EOF)Then
processParm="No Data"
else
processParm=rs.getString()
end if
set rs=Nothing
End Function
%>

What we are doing here is getting a single querystring parameter consisting of the ZIPCODE we want to look up from the Zipcodes table. Note that I check to see if the length of the parameter is less than 5 characters. This is important because as you'll see shortly in the client -side HTM page we are "polling" this function with a setTimeout as a sort of "poor man's callback function", and we want to make sure that if the user hasn't finished typing in a revised zipcode, they don't get back an error.

So if the zipcode is 5 character or more, we return a cookie consisting of the result of the processParm function call.

The processParm function simply opens a connection and does a SQL select with the parm value to get back our matching city and state. Now I've kept this really simply using getString as our data in this case simply consists of a city and state. You could certainly use getRows to put more complicated results into an array, serialize the array into a string using some delimiter character, and use the split function on the client to parse it apart. You could even construct a valid XML document, and return same as the cookie to the client. Just bear in mind that since this is only a browser cookie, you won't be able to cram too much data into it. Notice also that we are not returning any HTTP "response" as the result of this function call. We are only setting a cookie.

Now let's switch to the client side were the real magic takes place:

<script>
var tmID;
function requestRSCookie( parm ){
tmID= window.setTimeout("showResult('"+zippy.value+"');",200); // callback func to give cookie time to be set...
var i = new Image();
var d = new Date();
i.src = "ProvidecookieRS.asp?u=" + d.getTime() + "&p=" + parm;
var g = "";
g =getCookie("RSCookie");
return g.replace("+", " ")
}
function getCookie(sName){
var sCookie = document.cookie.split("; ");
for (var i=0; i < sCookie.length; i++){
var sCookiePart = sCookie[i].split("=");
if (sName == sCookiePart[0])
{
return unescape(sCookiePart[1]);
}
}
return "";
}

function showResult( parm){
test =requestRSCookie(parm);
var c = getCookie("RSCookie");
if ( c != null ){
CityState.innerText=c.replace("+", " ");
c=getCookie("RSCookie");
window.clearTimeOut(tmID);
}
CityState.innerText= c.replace("+", " ");
window.clearTimeOut(tmID);
}
</script>
<HTML>
<HEAD>
<TITLE>Remote Scripting with Cookies Demo</TITLE>
</HEAD>
<BODY>
<BASEFONT FACE=Verdana>
<CENTER><h3>Remote Scripting with Cookies Demo</h3></CENTER><BR>
<Table cellpadding=4 cellspacing =2 border="0" align="center">
<TR><TD><input type=text id=zippy onChange="showResult(zippy.value);"></TD><TD>enter zip code, TAB out for result.</TD></tr>
<TR><TD><input type=text id=CityState size=30></td><TD>City /State</td></tr>
</TABLE>
</BODY>
</HTML>

What happens here (in simplified form) is this:

First we have an input field to accept a zipcode. The onchange event fires the showResult function, passing the value of the formfield to it.

Then showResult assigns the result of requestRSCookie(parm) to the variable "test".

The requestRSCookie function sets the window.setTimeout on the showResult function to 200 milliseconds. We do this because we need to keep checking until the cookie has actually been planted. There are a number of other ways to do this, but I chose this one as it is relatively simple, and has the added benefit that if we change the value of our zipcode field, we get back the new result automatically. If the cookie is planted before we've typed in a full five characters, or if the zipcode is invalid, we just get a cookie containing a blank string, so nothing "bad" happens.

The requestRSCookie function creates two objects, a dateTime object which is simply used to make each URL unique to prevent caching, and an Image object. When we set the SRC property of the image object to our server side script (with the querystring parameters appended), the browser tries to load the image. Of course, there is no image, but the server side script does set our cookie containing the results. Of course, in your work you'll need to set the URL of the "Image" to the actual http URL of your server script.

The rest is pretty much self-explanatory. SetTimeout keep firing showResult until we get back a cookie with something in it. we Replace any "+" signs with a space, and display the result in the second formfield, "CityState".

Elegant, simple, and very lightweight! Thanks Brent, for an interesting idea.

 

Download the code that accompanies this article


Peter Bromberg is an independent consultant specializing in distributed .NET solutionsa Senior Programmer /Analyst at in Orlando and a co-developer of the NullSkull.com developer website. He can be reached at info@eggheadcafe.com