Configuring Servers and Databases with Chrome
(Page 1 of 5 )
In this second part of a four-part article that explains how to prepare XUL Internet applications for a commercial setting, you'll learn how to configure servers and build a database. This article is excerpted from chapter four of
Programming Firefox, written by Kenneth C. Feldt (O'Reilly, 2007; ISBN: 0596102437). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.
The client-side request
Firefox supports the XMLHttpRequest, which is generally modeled after Microsoft’s IXMLRequestdesign. We can use the request to retrieve either simple text strings, or XML fragments that may be parsed and passed to the interface document’s Document Object Model (DOM) structure.
To use the request, JavaScript scripts create an instance of anXMLHttpRequestobject to be sent to the server, passing the object a reference to a callback function to be invoked once the request is completed. The callback function then takes whatever action is determined by the response.
Table 4-1 summarizes the functions and properties of the XMLHttpRequestobject most relevant to us for the upcoming exercise.
Table 4-1. XMLHttpRequest methods and properties
| Method/Property | Description |
| open(sendMethod, sendURL, doAsync) | sendMethod=POST|GET. sendURL= query string. doAsync= ifTRUE, return upon transmission of request. |
| .onreadystatechange | Function called when the request’s “ready” state changes. |
| send(null) | Sends the request to the server. |
| .readyState | Monitored within the callback;code == 4signals that the request is completed. |
| .status | Monitored within the callback;code==200signals that the server was successful in executing the request. |
| .responseText | Accesses the text returned by the server to be parsed and processed in an application-specific format. |
| .responseXML | Accesses the text returned by the server when the text is presumed to consist of an XML document. |
Before we start to code, we need to decide on a send/receive protocol between our client application and the server. We will use a very simple URL string to send commands to our server:
command=someCommand¶m1=val1¶m2=val2...
From our server, we will expect a comma-delimited string for a response:
RetCode=ReturnCode,retKey1=retVal1...
We will expect the first value token to be a case-insensitivetrue|falsevalue to indicate the success of the command.
We will now change our newssearch.js file to implement a few modifications for our client/server model:
- We will build a genericdoServerRequestfunction to build anXMLHttpRequest object and send it to the server. To support that function, we will also create acommandArgobject to hold name-value pairs of arguments that can be used to populate an array of arguments. The function will set theasyncflag in theopen function toTRUE, meaning that control will immediately return to the application once the request is sent.
- We will change our login-button command handler to call the newly createddoServerRequestfunction.
- We will change the logic to move successful and failed paths for login into separate functions.
- We will write some JavaScript to add a callback function to interpret the response from the server and call the successful or failed login functions:
function genericBtnHandler(event){
try { // try block
var infoString = "Type = " + event.type + ",";
infoString += "Target = " + event.target + ",";
infoString += "Target.tagName = " + event.target.tagName + ",";
infoString += "Target.id = " + event.target.id + ".";
dump(infoString + "\n");
} // try block
catch (e) {
alert("genericBtnHandler exception: " + e);
}
}
function doLogin(event) {
try { // try
var theArgs = new Array;
theArgs[0] = new commandArg("un",document.getElementById("userName").value);
theArgs[1] = new commandArg("pd",document.getElementById("password").value);
doServerRequest("login",theArgs);
} // try
catch (e) { //
alert("doLogin exception: " + e);
}//
}
//
// Dynamically assign our event handler properties
// function initialize() {
try {
document.getElementById("B1").addEventListener("command",genericBtnHandler,true);
document.getElementById("B2").addEventListener("command",genericBtnHandler,true);
document.getElementById("B3").addEventListener("command",genericBtnHandler,true);
//
// Add a login script
document.getElementById("loginButton").addEventListener("command",doLogin,true);
}
catch (e) {
alert ("Exception: " + e);
}
}
function loginOK() {
var theParent = document.getElementById("contentArea");
while(theParent.childNodes.length
!= 0)
theParent.removeChild(theParent.childNodes[0]);
// Now re-create a welcome area
theParent.style.backgroundColor = "LightSeaGreen";
theParent.style.borderColor = "gray";
theParent.style.borderStyle = "ridge";
var leftSpacer = document.createElement("spacer");
leftSpacer.setAttribute("flex","1");
theParent.appendChild(leftSpacer);
var newDescription = document.createElement("description");
var newDescriptionText = document.createTextNode("Welcome!");
newDescription.appendChild(newDescriptionText);
theParent.appendChild(newDescription);
var rightSpacer = document.createElement("spacer");
rightSpacer.setAttribute("flex","1");
theParent.appendChild(rightSpacer);
}
function commandArg(argKey,argValue) {
this.key = argKey;
this.value = argValue;
}
function loginFail(){
document.getElementById("msgDescription").style.backgroundColor="red";
document.getElementById("msgDescription").style.color="white";
document.getElementById("msgDescription").childNodes[0].nodeValue =
"User not authenticated.";
document.getElementById("userName").value = "";
document.getElementById("password").value = "";
}
//
// CreateServerRequest
//
var theServerRequest;
//
// commandArgs is an array of arguments, each element
// is converted into a PHP GET URL field
function doServerRequest(commandString,commandArgs) {
theServerRequest = new XMLHttpRequest();
var theString ="http://localhost/ doCommand.php?"+"&command="+commandString+"&";
for (var i = 0; i < commandArgs.length; i++) { // build remaining parameters
theString += commandArgs[i].key + "=" + commandArgs[i].value ;
if (i != (commandArgs.length-1)) theString += "&";
} // build remaining parameters
theServerRequest.onreadystatechange = retrieveServerResponse;
theServerRequest.open("GET",theString,true);
theServerRequest.send(null);
}
function retrieveServerResponse() {
if (theServerRequest.readyState == 4) { // all done
// Check return code
if (theServerRequest.status == 200) { // request terminated OK
alert("Response is " + theServerRequest.responseText);
if (theServerRequest.responseText == "retcode=true") { // all OK
loginOK();
} // all OK
else loginFail();
} // request terminated OK
else { // something is wrong
alert("Response failed.");
} // something is wrong
} // all done
}
We wrote thedoServerRequestfunction to take an array of input arguments. The code then steps through the array to build a URL containing our completeGET request URL.
The request object calls theretrieveServerResponsefunction each time the state changes, and once it reaches"4"(a code that means the server has completed the request), it checks for a status of200(meaning the server successfully completed the request) and finally parses the text returned by the server to see whether the user is authenticated.
Next: The server-side response >>
More Web Standards Articles
More By O'Reilly Media
|
This article is excerpted from chapter four of Programming Firefox, written by Kenneth C. Feldt (O'Reilly, 2007; ISBN: 0596102437). Check it out today at your favorite bookstore. Buy this book now.
|
|