Monday, March 07, 2005

Fwd: Undelivered Mail Returned to Sender

---------- Forwarded message ----------
From: Mail Delivery System
Date: Thu, 3 Mar 2005 15:05:22 -0800 (PST)
Subject: Undelivered Mail Returned to Sender
To: itsdifferent.group+caf_its-different.blog=blogger.com@gmail.com

This is the Postfix program at host blogger.com.

I'm sorry to have to inform you that your message could not be
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

The Postfix program

(expanded from
): Command died with status 1: "IFS='
'&&exec /home/bloggermail/processmail2||exit 75 #bloggermail"

Final-Recipient: rfc822; bloggermail+its-different.blog@blogger.com
Original-Recipient: rfc822; its-different.blog@blogger.com
Action: failed
Status: 5.0.0
Diagnostic-Code: X-Postfix; Command died with status 1: "IFS=' '&&exec
/home/bloggermail/processmail2||exit 75 #bloggermail"

---------- Forwarded message ----------
From: Samir Prabhu
To: itsdifferent@yahoogroups.com
Date: Wed, 2 Mar 2005 00:47:38 -0800 (PST)
Subject: [itsdifferent] Dynamic Web interfaces with XML

Very Dynamic Web Interfaces

<script></script> One of the classic drawbacks to building a
web application interface is that once a page has been downloaded to
the client, the connection to the server is severed. Any attempt at a
dynamic interface involves a full roundtrip of the whole page back to
the server for a rebuild--a process which tends to make your web app
feel inelegant and unresponsive. In this article, I'll be exploring
how this problem can be tackled with the use of JavaScript and the
XMLHttpRequest object.

I'm sure you're familiar with the traditional interface model for a
web application. The user requests a page from the server, which is
built and delivered to the browser. This page includes an HTML form
element for capturing data from the user. Once the user posts their
input back to the server, the next page can be built and served based
on the input, and so the process continues. This is largely dictated
by the nature of HTTP and differs from the traditional desktop
application model of an interface which is inherently connected to the
application layer.

Take the simple example of filling out a serial number box to register
a desktop app on a platform like Microsoft Windows. According to
convention, once you've finished typing that tiresome string of
alphanumeric into the little boxes, a big green 'tick' icon appears to
indicate you've entered a valid code. This happens instantly as a
result of the interface being sewn to the application; as soon as you
finish typing the number, the application is able to check its
validity and respond.

Contrast this to the standard behavior of the same task represented
through a web interface. Sure, all the boxes for keying in the serial
number will look identical, but on completing input, the user would
need to submit the page back to the server for the input to be
validated. A new page would then load with a message to indicate
success or failure, and on failure, the user would need to go back and
try again ad infinitum.

So whilst it's not terribly common that a user would be asked to enter
a serial number into a web application, there are countless other
examples of user actions that can benefit from very fast reactions
from the interface, and when the business logic is all the way back at
the server, this can be difficult to achieve in a traditional web app.
Enter JavaScript

Through the use of JavaScript, a reasonable amount of logic can be
added to an HTML page in order to give timely feedback to user
interactions. This has some major drawbacks, however. The first
problem is that, as the JavaScript has been delivered to the browser
along with the page, that logic has been opened up to interrogation.
This might be fine for checking the format of an email address but
would be no good for something like our serial number example, as the
exposure of the method of verifying that input would compromise the
integrity of the serial number mechanism.

The second problem with including any serious logic within the page is
that the interface layer is simply not the place for serious logic.
This belongs in the application layer, which is way back at the
server. The problem is compounded by the fact that JavaScript cannot
usually be relied upon to be available at the client. Whilst the
majority of users are able and willing to run JavaScript in their
browser, a considerable number prefer not to, or browse with a device
where JavaScript is either unavailable or makes no sense. Therefore,
any logic operations performed with JavaScript at the client must be
verified at the server in case the operation never occurred.
The XMLHttpRequest Object

A solution to these problem presents itself in the form of the
XMLHttpRequest object. This object, first implemented by Microsoft as
an ActiveX object but now also available as a native object within
both Mozilla and Apple's Safari browser, enables JavaScript to make
HTTP requests to a remote server without the need to reload the page.
In essence, HTTP requests can be made and responses received,
completely in the background and without the user experiencing any
visual interruptions.

This is a tremendous boon, as it takes the developer a long way
towards achieving the goals of both a responsive user interface and
keeping all the important logic in the application layer. By using
JavaScript to ferry input back to the server in real time, the logic
can be performed on the server and the response returned for
near-instant feedback.
The Basics

Due to its history, and not yet being embodied in any public standard
(although something similar is in the works for the proposed W3C DOM
Level 3 Load and Save spec), there are two distinct methods for
instantiating an XMLHttpRequest object. For Internet Explorer, an
ActiveX object is used:var req = new
ActiveXObject("Microsoft.XMLHTTP");

For Mozilla and Safari, it's just a native object:var req = new
XMLHttpRequest();

Clearly, as a result of this inconsistency, it's necessary to fork
your code based on support for the appropriate object. Whilst there
are a number of methods for doing this (including inelegant browser
hacks and conditional comment mechanisms), I believe it's best to
simply test for support of either object. A good example of this can
be found in Apple's developer documentation on the subject. Let's take
their example:var req;

function loadXMLDoc(url)
{
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send(null);
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send();
}
}
}

A particularly important property to note is the onreadystatechange
property. Note how it is assigned to a function processReqChange. This
property is an event handler which is triggered whenever the state of
the request changes. The states run from zero (uninitialized) through
to four (complete). This is important because our script isn't going
to wait for the response before continuing. The HTTP shenanigans are
initiated, but then they carry on out of process whilst the rest of
the script runs. Due to this, it's not as simple as having loadXMLDoc
return the result of the request at the end of the function, because
we don't know if we'll have a response by then or not. By having the
function processReqChange check for the state changing, we can tell
when the process has finished and carry on only if it has been
successful.

With this in mind, a skeleton processReqChange function needs to check
for two things. The first is the state changing to a value of 4,
indicating the process complete. The second is to check the HTTP
status code. You'll be familiar with common status codes like 404
(file not found) and 500 (internal server error), but the status code
we're looking for is good old 200 (ok), which means everything went
well. If we get both a state of 4 and an HTTP status code of 200, we
can go right ahead and start processing the response. Optionally, of
course, we can attempt to handle any errors at this point, if, for
example, the HTTP status code was something other than 200.function
processReqChange()
{
// only if req shows "complete"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
// ...processing statements go here...
} else {
alert("There was a problem retrieving
the XML data:\n" + req.statusText);
}
}
}
In Practice

I'm going to work up a practical example so we can get this going.
Most web applications have some method of signing up users, and it's
common to ask the user to pick a username to use for the site. Often,
these need to be unique, and so a check is made against the database
to see if any other user already has the username a new recruit is
trying to sign up with. If you've ever signed up for a web mail
account, you'll know how infuriating it is cycling around the process
trying to find a username that isn't already taken. It would be really
helpful if that check could be made without the user leaving the page.

The solution will involve four key elements: an XHTML form, a
JavaScript function for handling the specifics of this case, our pair
of generic functions (as above) for dealing with HTTP, and finally, a
script on the server to search the database.
The Form

Here's the easy bit--a simple form field to collect the user's chosen
username. An onblur event handler is used to fire the script. In order
to display a friendly message to the user if the name is taken, I've
embedded it in the form and hidden it with CSS. This should prove a
little less violent than a standard JavaScript alert box.id="username" name="username" type="text"
onblur="checkName(this.value,'')" />

The CSS defines a class for hidden and also one for showing the error.
Call that one error.span.hidden{
display: none;
}

span.error{
display: inline;
color: black;
background-color: pink;
}
Handling the Input

The checkName function is used to handle the input from our form. Its
job is to collect the input, decide which script on the server to
present it to, invoke the HTTP functions to do the dirty work on its
behalf, and then deal with the response. As such, this function has to
operate in two modes. One mode receives input from the form, the other
the response from the HTTP request. I'll explain the reason for this
in the next section.function checkName(input, response)
{
if (response != ''){
// Response mode
message = document.getElementById('nameCheckFailed');
if (response == '1'){
message.className = 'error';
}else{
message.className = 'hidden';
}
}else{
// Input mode
url =
'http://localhost/xml/checkUserName.php?q=' + input;
loadXMLDoc(url);
}

}

Our response is going to be easy to deal with--it'll be a string of
either 1 or 0, with 1 indicating that the name is in use. Therefore,
the function changes the class name of the error message so it gets
displayed or hidden, depending. As you can see, the dirty work at the
server is being done by a script called checkUserName.php.
HTTP Heavy Lifting

As we saw earlier, the HTTP work is being done by two functions,
loadXMLDoc and processReqChange. The former can remain totally as-is
for the purposes of this example, with the only modifications needed
to the latter being a quick bit of DOM work.

You'll recall that by the time a successful response has been passed
to processReqChange, we're no long in a position to pass any sort of
return value back up the chain. Because of this, it's going to be
necessary to make an explicit function call to another bit of code in
order to do anything useful with the response. This is why our
checkName function has to run in two modes. Therefore, the main job of
processReqChange is to parse the XML coming back from the server and
pass the raw values back to checkName.

However, it is important that we keep these functions generic (we may
have multiple items on the page that need to make use of
XMLHttpRequest), and so hard-coding a reference to checkName at this
point would be foolhardy. Instead, a better design is to have the
server indicate the handling function as part of its response.version="1.0" encoding="UTF-8"
standalone="yes"?>

checkName
1

Parsing such a simple response should be no problem at all.function
processReqChange()
{
// only if req shows "complete"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
// ...processing statements go here...
response = req.responseXML.documentElement;

method =
response.getElementsByTagName('method')[0].firstChild.data;

result =
response.getElementsByTagName('result')[0].firstChild.data;

eval(method + '(\'\', result)');
} else {
alert("There was a problem retrieving the XML
data:\n" + req.statusText);
}
}
}

By using the responseXML property of the XMLHttpRequest object, we
have a ready-made XML object we can traverse with the DOM. By grabbing
content of the method element, we know which local function to execute
along with the result. Once you've finished testing, it's probably a
good idea to dump the else clause from the above code, enabling the
function to fail silently.
The Server Script

The final piece in our jigsaw is the script on the server to accept
the request, process it, and return an XML document in response. For
the purposes of our example, this script looks up usernames in a
database table to determine whether a name is already in use. For
brevity, my example PHP script below just checks against two
hard-coded names, 'Drew' and 'Fred'.header('Content-Type: text/xml');

function nameInUse($q)
{
if (isset($q)){
switch(strtolower($q))
{
case 'drew' :
return '1';
break;
case 'fred' :
return '1';
break;
default:
return '0';
}
}else{
return '0';
}

}
?>
standalone="yes"?>'; ?>

checkName
echo nameInUse($_GET['q']) ?>

Of course, the logic used to verify the availability of the username
in this script can be reused after the form is submitted to recheck
that the name is available. This is an important step, since if
JavaScript was not available at the client, this check would not have
yet taken place. Additionally, on a busy site, a username which
checked out OK at the time the user was filling the form in may have
been taken by the time the form is submitted.

Perhaps as a next step, if you're interested in playing with this some
more, you could add the ability for the server to return a list of
suggested alternative usernames if the suggested name is taken.

________________________________
Celebrate Yahoo!'s 10th Birthday!
Yahoo! Netrospective: 100 Moments of the Web

Note: This Group is not a Job Searching Group, so please co-operate
and dont transfer any kind of job related material across this
Group.AnyOne doing so can be banned from the Group
Thanx , Group Co-Ordinators

Yahoo! Groups Sponsor
ADVERTISEMENT

________________________________
Yahoo! Groups Links

To visit your group on the web, go to:
http://groups.yahoo.com/group/itsdifferent/

To unsubscribe from this group, send an email to:
itsdifferent-unsubscribe@yahoogroups.com

Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.

--
--
Regards...
/*******************************
itsDifferent
http://its-Different.blogspot.com
http://groups.yahoo.com/group/itsdifferent/join
http://groups.msn.com/its-Different/join
http://groups-beta.google.com/group/itsdifferent
*******************************/

3 comments:

job opportunitya said...

Powerful blog. The site was incredible and will be
back again! Web surfing helps to find good blogs like
this one.
Hey son, you need to check out my plastic surgery statistics blog!

job opportunitya said...

Captivate blog. I surf the web for blogs this
nature.The site are wonderful and will be returned to
again!
Check out my beverly hills plastic surgery blog, please!

job opportunitya said...

Irresistible blog. I look for blogs like this one
when time allows me to. I enjoyed the site and I'll
check it next time!
I can't explain, but you need to check my arizona center plastic surgery tucson az blog!